Home > Software engineering >  React Router with Suspense Lazy Load page always show my notFound page under all my components
React Router with Suspense Lazy Load page always show my notFound page under all my components

Time:11-23

I have a component that creates the dynamic routes with a routes[] list, but when I add the route for "not found" NotFoundUrl page it always shows it to me in all components.

The other routes always work fine but when adding the route for 404 this page is always rendered on top of the others and the idea is that if a route does not exist in the previously added ones, it will render only the NotFoundUrl page.

ruotes.tsx

const routes: Route[] = [
  {
    path: '/home',
    name: 'admin',
    icon: 'icon-signal',
    component: MyHomePage,
    layout: '/admin',
    text: 'Wellness',
  },
  {
    path: '/profile',
    name: 'admin',
    icon: 'icon-profile',
    component: ProfilePage,
    layout: '/admin',
    text: 'Profile',
  },
  {
    path: '/support',
    name: 'support',
    icon: 'default',
    component: LandingPage,
    layout: '/',
    text: 'Support',
  },
  {
    path: '*',
    name: 'notfound',
    icon: '',
    component: NotFoundUrl,
    layout: '/admin',
    text: 'Notfound',
  },
]

AdminLayout.tsx

return (
  <Fragment>
    <div className="adminContainer">
      <Switch>
        <Suspense fallback={<div></div>}>
          {routes.map((route, i) => {
            if (route.layout === '/admin') {
              return (
                <Route
                  path={route.layout   route.path}
                  component={route.component}
                  key={i}
                  exact
                />
              );
            }
          })}
        </Suspense>
      </Switch>
    </div>
  </Fragment>
)

My app.tsx:

const App = () => {
  return (
    <Switch>
      <Route path="/admin" render={(props) => <AdminLayout />} />
      <Route path="/auth" render={(props) => <AuthLayout />} />
      <Route path="/soporte" render={(props) => <LandingPage />} />
      <Route path="/pago-movil" render={(props) => <GoToApp />} />
      <Redirect from="/" to="/auth/login" />
    </Switch>
  );
};

export default App;

I tried changing the route in various ways but the problem persists.

I tried this:

{
  path: '/*',
  name: 'notfound',
  icon: '',
  component: NotFoundUrl,
  layout: '/admin',
  text: 'Notfound',
}

Also adding this in the Switch component

<Route path="/admin/*" component={NotFoundUrl} />

CodePudding user response:

The Switch component exclusively returns the first matching Route or Redirect component, but since the Switch is only rendering a React.Suspense component it "matches" and renders that instead, and then all routes inside Suspense are inclusively matched and rendered just as if they are in a router.

Move the Switch component inside the Suspense so it can exclusively match and render routes again.

Example:

return (
  <Fragment>
    <div className="adminContainer">
      <Suspense fallback={<div></div>}>
        <Switch>
          {routes
            .filter(route => route.layout === '/admin')
            .map((route) => (
              <Route
                key={route.layout   route.path}
                path={route.layout   route.path}
                component={route.component}
                exact
              />
            ))
          }
        </Switch>
      </Suspense>
    </div>
  </Fragment>
)
  • Related