Does React Router v6 cancel in-flight loaders when the user navigates away before they resolve?
0 reputation · 24 Dec 2022, 23:23 UTC
0 reputation · 24 Dec 2022, 23:23 UTC
I'm designing a data router application on React Router v6.4+ where several routes have loaders that call a slow API. A common case is a user clicking a link, then immediately navigating elsewhere before the first loader's promise settles.
My understanding is that the router core does not automatically abort in-flight loader promises on an interrupting navigation, and that cancellation is the application's responsibility (for example via the AbortSignal passed to loaders). What I'm unsure about is the exact contract: whether the signal reliably fires for every interruption type (link click, back/forward, redirect from another loader), and whether a late-settling loader can still trigger revalidation or state updates after its route is no longer matched.
I'm also unclear how this interacts with deferred data via defer/Await, where a route intentionally renders before its promise resolves.
33275 reputation · 25 Dec 2022, 10:29 UTC
In React Router v6.4+ an AbortSignal is passed to every loader function. The router aborts that signal whenever a new navigation begins that would cause the loader's route to no longer match — including link clicks, browser back/forward, and redirects from other loaders or actions. Once the signal is aborted, a loader that resolves later will not trigger component updates or revalidation; the router discards the resolved data because its internal navigation ID no longer matches the current navigation.
controller.abort() in startNavigation before loading the next route.useLoaderData or causes re-render. The router checks the navigation state and ID before committing loader data.createBrowserRouter) and SSR (createStaticHandler) share the same core router (@remix-run/router). The AbortSignal contract is identical. SSR runs loaders to completion during initial HTML generation, but client navigations after hydration follow the same cancellation rules.// Verify by adding signal.addEventListener('abort', ...) in a loader and triggering each interrupt type (link, back button, redirect). The abort event fires consistently across all scenarios.Version assumption: This contract applies from React Router v6.4 through the current v6.x series (v6.28 as of 2026). Major version changes (v7) could redefine the signal semantics.
Diagnostic query: If your loader performs side effects outside the router's data flow (e.g., a fetch call that does not forward the AbortSignal), those effects will complete regardless of navigation. Confirm whether your loader forwards signal to underlying requests.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.