Reputation: 6639
Am using react router v6 and i would like to use the new loader to load the data before the component loads. So i have the following
In my index.js
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="*"
loader={async ({ params }) => {
console.log("index loader log"); //this logs
return true;
}}
element={<App />}
> </Route>
)
);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<RouterProvider router={router} />
);
in my app component i have nested routes like
const App = () => {
return (
<>
<Routes>
<Route path="auth/*" element={<AuthLayout/>}/>
<Route path="about"
loader={async ({ params }) => {
console.log("about child loader log"); //this doesnt log
return true;
}}
element={<AboutPage/>}/>
</Routes>
<h1>Testing app</h1>
</>
);
}
On the app component the loader on the Route path="about"
does not console.log when i visit the about route but the component is rendered. What am i missing for the loader to work on the child route.
Upvotes: 8
Views: 9252
Reputation: 202751
Based on some basic testing it seems that in order for the new RRDv6.4 data APIs to work you need to specify the complete routing configuration in the createBrowserRouter
function.
There does however appear to already be an issue filed with @remix-run/react-router
for this behavior as a reported bug, so you may want to follow it if it ever addressed/resolved. (I suspect it was you since the name is "geoffrey" and the timing is coincidentally about an hour ago around the same time as this post)
This above issue has since been closed with comment:
Descendant
<Routes>
trees do not participate in data loading (https://reactrouter.com/en/main/components/routes) since they cannot be known ahead of render-time. You'll need to lift your descendantroute
definitions up into the routes you pass tocreateBrowserRouter
.
The relevant information regarding the descendent routes and the new Data API can be found in the Routes
documentation in a note.
Note:
If you're using a data router like
createBrowserRouter
it is uncommon to use this component as it does not participate in data loading.
Hoist the entire route declaration to the parent creating the data router. The following does work with the loader function for the "/about"
route and About
component.
const router = createBrowserRouter(
createRoutesFromElements(
<Route
path="*"
loader={({ params }) => {
console.log("index loader log");
return "This is the App";
}}
element={<App />}
>
<Route path="auth/*" element={<AuthLayout />} />
<Route
path="about"
loader={({ params }) => {
console.log("about child loader log");
return "this is the about page";
}}
element={<AboutPage />}
/>
</Route>
)
);
The App
component should render an Outlet
for the nested routes to render their content into.
import { Outlet } from 'react-router-dom';
const App = () => {
return (
<>
<h1>Testing app</h1>
<Outlet />
</>
);
};
Upvotes: 10