react-admin
react-admin copied to clipboard
AppBar title hides on translation change
What you were expecting:
The page title, e.g. "configuration", is shown
What happened instead:
Title hides until a different, not language configuration, has been toggled
Steps to reproduce:
Go on the demo page, click on the profile badge and click on the link to the configuration page. Change the language.
Related code:
https://github.com/marmelab/react-admin/blob/master/examples/demo/src/layout/AppBar.tsx
Other information:
Seems like it's rendering before the language change has been applied, maybe?
Environment
- React-admin version: latest, 4.1.0
- Last version that did not exhibit the issue (if applicable):
- React version: 17.0.2
- Browser: Firefox 100.0.2, Chrome 101.0.4951.64
- Stack trace (in case of a JS error):
Thanks for the report. I'm not sure if the bug in in react-admin or in the demo itself, but there definitely is a bug.
What's weird is that I can't reproduce the problem in the Simple Example codesandbox, by switching the language from the user menu (the title doesn't disappear). It may be a sign that the problem lies in the way the Configuration component in the demo handles the title.
@fzaninotto ,I have a different issue with title, which might be related
I have a custom route under admin. When I load open a browser directly to this page http://localhost:3000/#/test, no title is displayed; however, if I navigate to this page from another page in my application, title is suddenly rendered
<CustomRoutes>
<Route
path='/test/*'
element={
<>
<Title title="test title"/>
<>Test page</>
</>
}
/>
</CustomRoutes>
In my case, it appears that the following code in <Title>
causes issues. The problem is element react-admin-title
does not exist when page is loading in new browser tab; however, after the page has successfully loaded, element react-admin-title
is created and subsequent calls to render Title result in proper title display.
const container =
typeof document !== 'undefined'
? document.getElementById('react-admin-title')
: null;
if (!container) return null;
I created a custom title component that addresses the bug that I see on fresh page load. Not sure if that fixes the bug on language change:
- I render RA Title if
react-admin-title
div exists - If the div does not, I wait for
SafeTitle
component mount and check for the div presence again:- If the div exists, I render RA title (that solved the issue)
- In case the element still does not exist, I wait for another 500ms and then render RA title
@fzaninotto , can we incorporate similar checks and delays in RA title?
Thanks
const SafeTitle = (props: TitleProps) => {
const [ready, setReady] = useSafeSetState(false)
const container = (document && document.getElementById('react-admin-title')) || null
useEffect(() => {
const tgt = (document && document.getElementById('react-admin-title')) || null
if (tgt) {
setReady(true)
return
}
const timer = setTimeout(() => {
setReady(true)
}, 500)
return () => {
clearTimeout(timer)
}
}, [setReady])
if (!ready && !container) return null
else return <Title {...props} />
}
The main issue may be related to a React bug that was fixed in React 18, according to https://github.com/facebook/react/issues/20141
Could you please report if the bug still exists with React 18?
@fzaninotto : We're on React v18.2.0 and unfortunately still getting this weird bug. App bar titles disappear across the entire site without any clearly-identifiable cause.
The issue seems still persists on latest react-admin 4.9.2 and react 18.2
Hi @fzaninotto @septentrion-730n , I believe this issue may not be related to the bug that you mentioned.
I think the bug is trigger because
- User sets the local and in the
I18nContextProvider
https://github.com/marmelab/react-admin/blob/d1889e46a5f284f5f56ec7136b4807becfc8e6b8/packages/ra-core/src/i18n/I18nContextProvider.tsx#L33 it forces a full page rerender by increasing the key. -
TitlePortal
gets rerendered https://github.com/marmelab/react-admin/blob/d1889e46a5f284f5f56ec7136b4807becfc8e6b8/packages/ra-ui-materialui/src/layout/TitlePortal.tsx#L12 , creating a new DOM element -
Title
is using an old copy of the DOM element after the rerender https://github.com/marmelab/react-admin/blob/d1889e46a5f284f5f56ec7136b4807becfc8e6b8/packages/ra-ui-materialui/src/layout/Title.tsx#L10 and still try to render into the non-existant portal.
I think the fix for this issue could be always trying to pass the key together into the context, and let <Title />
's useEffect depend on the key to see if the it should use a new DOM element. What do you think?
Thanks for your analysis @smeng9 !
I have opened https://github.com/marmelab/react-admin/pull/8846 to suggest another way to fix it: when the component gets rerendered, I also check if the container
we have in store still exists in the DOM and if not, I fetch the new one from the DOM.
Hopefully it will fix your issue too @panfiva :crossed_fingers: