Repository navigation
Fix blank page when the app rerenders during logout - #11435
Merged
Merged
Conversation
InternalRouter called createHashRouter in its render body, so every rerender of the component rendering <Admin> discarded the router and created a new one at the current URL. A navigation scheduled on the previous router then updated the URL without the current router ever seeing it, leaving a blank page - typically when an auth SDK notifies the app that the session was cleared while authProvider.logout() runs. Router state that does not live in the URL, such as a navigation blocked by useBlocker, was lost the same way. The router is now created once. As it keeps the route element it was created with, that element reads the children from a context instead of closing over them, so children updates still reach the router. The basename can only be set at creation time, so RouterWrapper remounts InternalRouter when it changes. Closes #11431 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3 of 4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fixes #11431
InternalRoutercallscreateHashRouterin its render body, so every rerender of the component rendering<Admin>discards the router and creates a new one at the current URL. A navigation scheduled on the previous router then updates the URL without the current router ever seeing it: the URL becomes#/loginbut the page stays blank.This happens whenever something above
<Admin>rerenders whileauthProvider.logout()runs - a common pattern with auth SDKs, which notify a context provider when the session is cleared.Router state that does not live in the URL is lost the same way. A navigation blocked by
useBlocker(the "unsaved changes" guard) silently disappears when the parent rerenders.Solution
Create the router once.
The router keeps the route element it was created with, so that element can no longer close over the children, or the whole tree under
<Admin>would be frozen at its first render (dynamic resources, routes behind permissions, anything passed down from above<Admin>would stop updating). It now reads the children from a context placed above theRouterProvider, so children updates still reach the router.The
basenamecan only be set when the router is created, soRouterWrapperremountsInternalRouterwhen it changes. Abasenamechange therefore recreates the router, as before - but a plain rerender no longer does.How To Test
yarn test-unit packages/ra-core/src/routing/adaptersThe three tests each fail without the corresponding part of the fix:
should not lose the navigation state when the parent rerenders- a navigation blocked byuseBlockersurvives a parent rerendershould rerender the children when the parent rerenders- the tree under<Admin>still receives updatesshould take the new basename into account when it changesThe blank page from the issue itself only reproduces with React 19 and react-router 7, so it is not covered by a unit test here; it was verified manually with the issue's reproduction (react-admin built from this branch, React 19.3.1, react-router 7.18.4): the login page now renders instead of a blank page.
Additional Checks
masterfor a bugfix or a documentation fix, ornextfor a feature🤖 Generated with Claude Code