React Router v6.4 loader cache does not automatically revalidate on navigation
0 reputation · 05 Jun 2024, 06:27 UTC
0 reputation · 05 Jun 2024, 06:27 UTC
When a user navigates away from a route and returns to it without changing the matched route, the loader function should return up‑to‑date data reflecting any changes that occurred in the data source during the interval.
React Router v6.4 caches loader results and does not automatically invalidate or refresh that cache on a navigation that leaves the route match unchanged. The team has discussed adding a built‑in stale‑while‑revalidate mechanism or an opt‑in revalidation flag, but no decision has been made, leaving the behavior as an open design question.
useNavigation or useFetcher without duplicating caching logic across components?34275 reputation · 05 Jun 2024, 07:30 UTC
React Router v6.4+ does not automatically re-execute loaders when navigating to a route that is already active and has unchanged parameters. To force a data refresh when returning to a route or updating the view without a URL change, you must use the useRevalidator hook.
To manually trigger a refresh of all active loaders on the current page, implement the useRevalidator hook within your component:
import { useRevalidator } from "react-router-dom";
function MyComponent() {
const revalidator = useRevalidator();
const handleRefresh = () => {
// This triggers all active loaders to re-run
revalidator.revalidate();
};
return (
<button onClick={handleRefresh}>
Refresh Data
</button>
);
}
The behavior you are observing is intended. React Router optimizes performance by avoiding redundant network requests if the route match remains identical. Revalidation is typically tied to mutations; when a Form is submitted or useSubmit is called, the router automatically invalidates the cache and re-runs all active loaders to ensure the UI reflects the server-side changes.
Because there is currently no built-in "stale-while-revalidate" configuration or a per-route revalidateOnNavigate flag, the responsibility for cache invalidation falls to the application level. You have two primary paths:
action functions for data mutations, which trigger automatic revalidation.useRevalidator().revalidate() for event-driven refreshes (e.g., window focus or timer-based updates).You can verify this behavior by adding a console.log("Loader executed") inside your loader function. You will notice the log does not appear when navigating back to the same route, but it will appear immediately after calling revalidator.revalidate() or submitting a Form.
Diagnostic Detail Needed: Are you attempting to refresh data based on a specific event (like a WebSocket notification) or simply upon the user clicking a navigation link to the current page?
Use comments to ask for clarification. Post a solution as an answer.
34,275 reputation · 05 Jun 2024, 15:03 UTC
When the route match stays the same, React Router v6.4 returns the cached loader result. To refresh data without changing the URL you can call the revalidate function from either useNavigation or useFetcher. A common pattern is to attach a useEffect that watches navigation.state and calls fetcher.revalidate() on focus or interval, ensuring the loader runs again while keeping the cache keyed to the location.