Lazy loading with react router v6 beta

Viewed 1888

This is my app.js using react router dom v6.0.0 beta.

const App = () => {
  const routing = useRoutes(routes)
  return (
    <AuthProvider>
      <MuiThemeProvider theme={theme}>
        <GlobalStyles />
        {routing}
      </MuiThemeProvider>
    </AuthProvider>
  )
}

And routes are in routes.js.

const routes = [
  {
    path: "/",
    element: <LoggedOutLayout />,
    children: [
      {
        path: "auth",
        element: <AuthLayout />,
        children: [
          {
            path: "/register",
            element: <Register />,
          },
          {
            path: "/login",
            element: <Login />,
          },
          { path: "", element: <Navigate to="/auth/login" /> },
          { path: "/", element: <Navigate to="/auth/login" /> },
        ],
      },
      { path: "404", element: <NotFound /> },
      { path: "*", element: <Navigate to="/404" /> },
      { path: "", element: <Navigate to="/app/dashboard" /> },
      { path: "/", element: <Navigate to="/app/dashboard" /> },
]
.......

How do i implement lazy loading in v6? I'm thinking React.Suspence in App.js and React.lazy in routes.js. Any feedback is appreciated. Thanks

1 Answers

It's Probably too late to answer your question, you might already find out how to implement code splitting by route with react and the latest react-router-dom v6 api.

But I'll try to answer this question anyway.

I just happened to using the v6 on another project I had the other day, and here's my approach.

Firstable, just follow the guide from react's official documentation on React.lazy section, and import your pages (the element part of routes)...

const { Lazy } from 'react';
const LoggedOutLayout = Lazy(() => import('../your/path/to/LoggedOutLayout'));
...
// I'll skip the others, you know the drill.

const routes = [
  {
    path: "/",
    element: <LoggedOutLayout />,
    children: [
      {
        path: "auth",
        element: <AuthLayout />,
        children: [
          {
            path: "/register",
            element: <Register />,
          },
          {
            path: "/login",
            element: <Login />,
          },
          { path: "", element: <Navigate to="/auth/login" /> },
          { path: "/", element: <Navigate to="/auth/login" /> },
        ],
      },
      { path: "404", element: <NotFound /> },
      { path: "*", element: <Navigate to="/404" /> },
      { path: "", element: <Navigate to="/app/dashboard" /> },
      { path: "/", element: <Navigate to="/app/dashboard" /> },
]
.......

Secondly, I call useRoutes() in a function component, I name it as Routes in my case.

const Routes = () => {
  const elements = useRoutes(routes);

  return elements;
}

Then, include this component in App.js, and wrap it with <Suspense/>

const App = () => {
  return (
    <AuthProvider>
      <MuiThemeProvider theme={theme}>
        <GlobalStyles />
        <BrowserRouter>
          <Suspense fallback={<div>Loading...</div>}>
            <Routes/>
          </Suspense>
        </BrowserRouter>
      </MuiThemeProvider>
    </AuthProvider>
  )
}

And done.

I'm not sure if you can wrap {element} directly with <Suspense/>, I haven't test it yet. But that's something you can try.

Related