0

I am using React Router v6 with Suspense to lazy-load components and display a fallback UI (FallBackUI) while loading. However, FallBackUI only works correctly for QrHome and Home but does not appear when navigating to Food.

import { createBrowserRouter } from "react-router-dom";
import { Suspense } from "react";
import Layout from "../containers/Layout";
import FallBackUI from "../components/FallBackUI";
import NoMatchRoute from "../pages/NoMatchRoute";
import components from "./Components";

const routes = createBrowserRouter(
  [
    {
      element: <Layout />,
      children: [
        {
          path: "/",
          element: (
            <Suspense fallback={<FallBackUI />}>
              <components.QrHome />
            </Suspense>
          ),
        },
        {
          path: "/qr/:areaId/:qrId",
          children: [
            {
              index: true,
              element: (
                <Suspense fallback={<FallBackUI />}>
                  <components.Home />
                </Suspense>
              ),
            },
            {
              path: "food",
              element: (
                <Suspense fallback={<FallBackUI />}>
                  <components.Food />
                </Suspense>
              ),
            },
],
},
  {
          path: "*",
          element: <NoMatchRoute />,
        },
      ],
    },
  ]
);
import { lazy } from "react";

const QrHome = lazy(() => import("../pages/QrHome"));
const Home = lazy(() => import("../pages/Home"));
const Food = lazy(() => import("../pages/Food"));

export default {
  QrHome,
  Home,
  Food,
};

import styles from "./index.module.scss";
import CustomLoader from '../CustomLoader';

const FallBackUI = () => {
  return (
    <div className={styles["fall_back"]}>
      <CustomLoader />
    </div>
  );
};

export default FallBackUI;

I tried implementing a Suspense fallback using FallBackUI, expecting it to display a loading state for all lazily loaded components (QrHome, Home, Food,..). However, the fallback only works for QrHome and Home, while other components load without showing FallBackUI.

I expected FallBackUI to appear whenever a lazily loaded component was being fetched. Instead, it only appears for QrHome and Home, while Food and other routes load directly without the fallback

4
  • I've copy/pasted your code into a running CodeSandbox and the lazy suspense fallback is rendered on all lazy-loaded route components as it seems is expected. I'm unable to reproduce the issue you describe. Can you edit to provide better details? See if you can create a sandbox of your own that reproduces the problem that readers can inspect live? Commented Feb 21 at 17:43
  • Thanks for checking! You can reproduce the issue by cloning this repo: github.com/nobinsj/my-test-app.git Clone the repo and checkout the setup-base branch : git checkout setup-base npm install npm run dev I'm using node version 22.13.0 Commented Feb 22 at 7:06
  • Node 22 might be the issue, being still a little too new. I've seen random odd issues with devs on my team using it. Have you tried an older version like 16/18/20? Commented Feb 22 at 7:15
  • Yes, I’ve tried older versions like 16, 18, and 20, but the issue persists. Commented Feb 22 at 7:30

2 Answers 2

1

Use useLocation to get the current location and then pass location.key as the key prop to the . This forces React to unmount the previous route immediately when the location changes, which triggers the Suspense fallback while the new component loads.

This behavior stems from how React Router v6 (especially v6.4+ with its new data APIs and lazy loading) handles route transitions. In these newer versions, the previous route's component can remain mounted until the new one is fully loaded, which is why you might see the old page "frozen" during slow transitions.

import { Outlet, useLocation } from "react-router-dom";

const Layout = () => {
  const location = useLocation();
  return (
    <div>
      <header>Header</header>
      <main>
        <Outlet key={location.key} />
      </main>
    </div>
  );
};

export default Layout;
Sign up to request clarification or add additional context in comments.

Comments

0

Yes, In React router v6.4 and above, the previous page is mounted untill the new page is loaded

for unmounting the previous page immediatly when routed to another page, you have to add a key of the new route location to force unmount

 const location = useLocation();
      <Outlet key={location.key} />

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.