diff --git a/.changeset/calm-crabs-bathe.md b/.changeset/calm-crabs-bathe.md new file mode 100644 index 0000000000..89f3cc7dff --- /dev/null +++ b/.changeset/calm-crabs-bathe.md @@ -0,0 +1,5 @@ +--- +"react-router": patch +--- + +Fix a potential race condition that can occur when rendering a `HydrateFallback` and initial loaders land before the `router.subscribe` call happens in the `RouterProvider` layout effect diff --git a/packages/react-router/lib/components.tsx b/packages/react-router/lib/components.tsx index 1f20af4099..a86da605ec 100644 --- a/packages/react-router/lib/components.tsx +++ b/packages/react-router/lib/components.tsx @@ -667,6 +667,16 @@ export function RouterProvider({ // pick up on any render-driven redirects/navigations (useEffect/) React.useLayoutEffect(() => router.subscribe(setState), [router, setState]); + // Track race conditions where we finish initializing prior to the layout + // effect above running to register our listener. If we manually detect a + // change in `state.initialized`, automatically sync state. + let initialized = state.initialized; + React.useLayoutEffect(() => { + if (!initialized && router.state.initialized) { + logErrorsAndSetState(router.state); + } + }, [initialized, logErrorsAndSetState, router.state]); + // When we start a view transition, create a Deferred we can use for the // eventual "completed" render React.useEffect(() => {