-
I have a react-router v6 app with a pathless root route and a children routes with loader functions. I want to show a loader indicator in the root route while the data of the children is loading. I'm using the useNavigation hook to get the loading state to accomplish the task. However, my code is not working as I expected: the loading indicator doesn't render, the app only renders the UI AFTER the data of the child route is loaded. In fact, I noticed the approach that I used works when changing routes, but not for the first load. function Root() {
const { state } = useNavigation();
return (
<div>
<nav>
<Link to="/">Child 1</Link> <Link to="/c2">Child 2</Link>
</nav>
{state === "loading" && <div>loading...</div>}
<Outlet />
</div>
);
}
function loadFakeData() {
return new Promise((resolve) => setTimeout(() => resolve("somedata"), 2000));
}
const router = createHashRouter([
{
element: <Root />,
children: [
{ index: true, element: <div>Child 1</div>, loader: loadFakeData },
{ path: "/c2", element: <div>Child 2</div>, loader: loadFakeData }
]
}
]); This is my example app in Code Sandbox. Is anything wrong with my app? Is that the intended behaviour of react-router? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Ok, I just figured out this is intended behaviour. As all loaders for all active routes run in parallel, the root element is not rendered until all of them complete. To render a loading indicator for the first load scenario, one needs to pass a export default function MyApp() {
return <RouterProvider router={router} fallbackElement={<div>loading...</div>} />;
} |
Beta Was this translation helpful? Give feedback.
Ok, I just figured out this is intended behaviour. As all loaders for all active routes run in parallel, the root element is not rendered until all of them complete. To render a loading indicator for the first load scenario, one needs to pass a
fallbackElement
toRouterProvider
: