I have a react app where I have routes set up with the new data loaders from react-router-dom
import {
RouterProvider,
createBrowserRouter,
createRoutesFromElements,
Route
} from 'react-router-dom';
import Home from './components/Home';
import { rootLoader } from './loaders/rootLoader';
import { WelcomePage } from './components/Home';
import Pokemon from './components/Pokemon';
import { pokemonLoader } from './loaders/pokemonLoader';
import Error from './error/Error';
import './App.css';
const router2 = createBrowserRouter(
createRoutesFromElements([
<Route
element={<Home />}
loader={rootLoader}
path='/'
errorElement={<Error />}
>
<Route element={<WelcomePage />} index />
<Route
element={<Pokemon />}
loader={pokemonLoader}
path='pokemon/:name'
/>
</Route>
]
))
function App() {
return <RouterProvider router={router2} />
}
export default App;
The issue I have is the loader runs whenever a request is made from one of the routes children, e.g when I am on the welcome page, and I navigate to the Pokemon page, the rootLoader runs every single time on the parent route even when I am not using it on that page.
Is there a way to stop this? Is this the desired behaviour or is useEffect better in this instance?
1 Answer
This is by design. If you are manually updating the URL in the address bar this reloads the entire app. When the URL path is "/pokemon/<some pokemon id>" both the Home layout route and the Pokemon routes are loaded and will run their loader functions.
To resolve this you just need to actually navigate to the individual pokemon pages from within the app. For example, by rendering a navbar/links in Home that navigate to the specific pokemon pages.
Demo
Example output, the initial load with the root loader, then clicking through each link produces exactly 1 pokemon loader log per navigation.