11

how is it possible to create lazy loading with this syntax?

const A = React.lazy(() => import("./A"));
const B = React.lazy(() => import("./B"));

function App() {
return (<Routes>
    <Route
        path="firstPath"
        element={<A />} />
    
    <Route
        path="secondPath"
        element={<B />} />

</Routes>)
}

I was thinking that with this syntax A and B will be called when we pass them into element props and lazy loading wouldn't be possible.

0

4 Answers 4

17

You can wrap all in one Suspense:

const Home = lazy(() => import('./home'));
const About = lazy(() => import('./about'));

function App() {
  return (
    <Router>
      <Suspense fallback={<p> Loading...</p>}>
        <Routes>
          <Route path='/' element={<Home />} />
          <Route path='/about' element={<About />} />
        </Routes>
      </Suspense>
    </Router>
  );
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, been using this approach for a while - how would this work when using an Outlet though? Currently our whole app shows the fallback element - even though only the screen within the outlet is changing
2

It is, and you wrap the route's components in a Suspense wrapper.

React-router Lazy Loading

import { Suspense } from 'react';

const A = React.lazy(() => import("./A"));
const B = React.lazy(() => import("./B"));

function App() {
  return (
    <Routes>
      <Route
        path="firstPath"
        element={
          <Suspense fallback={<>...</>}>
            <A />
          </Suspense>
        }
      />
      <Route
        path="secondPath"
        element={
          <Suspense fallback={<>...</>}>
            <B />
          </Suspense>
        }
      />

    </Routes>
  );
}

8 Comments

I'm want to understand how lazy loading works in v6, there is difference between v5 to v6, in the previous version you should pass function not jsx that called createElement in first reload.
@alirezabinesh Lazy loading is a React thing, not a React-router-dom thing, it works exactly the same. Maybe I'm just misunderstanding your follow-on question? The above is the v6 route syntax.
react-router-dom help us to load component depending on the routing. but we passed called component to element props and i want to undrestand how the react-router-dom manage this? because when we call a component it is going to download and load.
@alirezabinesh I see, so your question is really something more like "How does React's lazy loading still work even though I passed a JSX literal of my component to the Route component?"
yes, in addition it has to load depends on the routing and it shouldn`t start loading at the first rendering
|
1

From v6.9.0. react-router supports lazy loading

const routes = createRoutesFromElements(
  <Route path="/" element={<Layout />}>
    <Route path="a" lazy={() => import("./a")} />
    <Route path="b" lazy={() => import("./b")} />
  </Route>
);

Docs: https://reactrouter.com/en/6.9.0/route/lazy

Github: https://github.com/remix-run/react-router/releases/tag/react-router%406.9.0

Comments

0

I don't think the React Router API affords this.

Code splitting is orthogonal to module loading, i.e. it can happen correctly without having achieved the behavior of: loading modules only once routed to.

Suspense can be placed anywhere above, and it must be by the time we ask a question like this as the application will fault without it.

When you write <A /> and <B /> in this parent component's rendering, as you have, as the Route element prop values, this causes the lazy module loading to happen then, during App render for any route, as these expressions are renderings of A and B.

If the React-Router API permitted lazy loading, it would let you defer rendering the routed-to component until that route is selected.

The typical way any value's computation is deferred in EcmaScript is by creating a function that returns the result. For example, in some other imaginary Router API, one might be permitted to write instead () => <A /> and () => <B />.

If at the basic level we end up with, internal to the imaginary Router library, const SelectedRoute: React.FC = () => <A />, then the lazy load of the A module would commence only once render arrives at <SelectedRoute />.

Thank you for reading.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.