I'm currently diving into React-Router, and I've set up my routing structure as follows:
const router = createBrowserRouter([
{
path: "/",
loader: rootLayoutLoader,
element: <RootLayout />,
children: [
{
path: "student",
loader: commonPageLoader,
element: <Student />,
},
{
path: "teacher",
loader: commonPageLoader,
element: <Teacher />,
},
],
},
]);
In my setup, the rootLayoutLoader
function is responsible for calling an API to gather some common information used by both the Teacher
and Student
components. Meanwhile, the commonPageLoader
function is calling an API based on the location path to fetch specific data.
Now, here's the issue I'm encountering: when I'm in the "/teacher"
route and click the "Teacher"
link, it triggers both the rootLayoutLoader
and commonPageLoader
functions. How can I prevent this double loading behavior while still ensuring the necessary data is fetched appropriately?
This is how the route loaders just generally work, they will revalidate their data under certain instances to keep the data in sync with routes.
There are several instances where data is revalidated, keeping your UI in sync with your data automatically:
- After an action is called from a
<Form>
.- After an action is called from a
<fetcher.Form>
- After an action is called from
useSubmit
- After an action is called from a
fetcher.submit
- When an explicit revalidation is triggered via
useRevalidator
- When the URL params change for an already rendered route
- When the URL Search params change
- When navigating to the same URL as the current URL
You are triggering the last point when clicking the "/teacher"
link when already on the "/teacher"
path.
You can implement the shouldRevalidate
prop on the route so that it doesn't revalidate when the URL path is the same.
Basic Example:
const shouldRevalidate = ({ currentUrl, nextUrl }) => {
return currentUrl.pathname !== nextUrl.pathname;
};
const router = createBrowserRouter([
{
path: "/",
loader: rootLayoutLoader,
element: <RootLayout />,
children: [
{
path: "student",
loader: commonPageLoader,
shouldRevalidate,
element: <Student />,
},
{
path: "teacher",
loader: commonPageLoader,
shouldRevalidate,
element: <Teacher />,
},
],
},
]);