material-ui: Textfield's autofocus in modal does not works with StrictMode and ReactDOM.createRoot
Duplicates
- I have searched the existing issues
Latest version
- I have tested the latest version
Current behavior 😯
When switching to ReactDOM.createRoot, opening a Dialog containing a TextField with autofocus, the field is not focused.
Expected behavior 🤔
No response
Steps to reproduce 🕹
reproducer: reproducer : https://codesandbox.io/s/dreamy-kowalevski-8eu5fb?file=/src/index.js
Context 🔦
The Dialog + field
export default function App() {
const [openPopup, setOpenPopup] = useState(false);
return (
<>
<Button onClick={() => setOpenPopup(true)}>
Open Modal
</Button>
<Dialog open={openPopup}>
<DialogContent>
<TextField autoFocus />
</DialogContent>
</Dialog>
</>
);
}
When initializing the project with the previous version of react it worked. But react triggered the deprecation about switching to ReactDOM.createRoot
import { render } from "react-dom";
render(
<StrictMode>
<App />
</StrictMode>,
document.getElementById("root")
);
When switching to ReactDOM.createRoot it does not worked
ReactDOM.createRoot(document.getElementById("root")).render(
<StrictMode>
<App />
</StrictMode>
);
But, if I remove the StrictMode, it work
ReactDOM.createRoot(document.getElementById("root")).render(
<App />
);
Your environment 🌎
`npx @mui/envinfo`
System:
OS: Linux 5.10 Debian GNU/Linux 11 (bullseye) 11 (bullseye)
Binaries:
Node: 17.9.0 - /usr/bin/node
Yarn: 3.1.1 - /usr/local/bin/yarn
npm: 8.10.0 - /usr/bin/npm
Browsers:
Chrome: 102.0.5005.61
Firefox: 91.10.0esr
npmPackages:
@emotion/react: ^11.9.0 => 11.9.0
@emotion/styled: ^11.8.1 => 11.8.1
@mui/base: 5.0.0-alpha.83
@mui/icons-material: ^5.8.2 => 5.8.2
@mui/material: ^5.8.2 => 5.8.2
@mui/private-theming: 5.8.0
@mui/styled-engine: 5.8.0
@mui/system: 5.8.2
@mui/types: 7.1.3
@mui/utils: 5.8.0
@types/react: ^18.0.10 => 18.0.10
react: ^18.1.0 => 18.1.0
react-dom: ^18.1.0 => 18.1.0
typescript: ^4.7.2 => 4.7.2
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 29
- Comments: 15 (3 by maintainers)
Just encountered this as well. Looks like there’s two options judging from the thread history for those on React 18+. Thanks for everyone who contributed.
disableRestoreFocusprop totrueon the Dialog component but lose that functionality, which is described as follows:So, if the user’s focus is inside a TextField, and they click a button or perform some action that causes a Dialog to open, the focus will not automatically return to that TextField when the Dialog is closed. Instead, they’ll need to manually click into it again.
This came up in a StackOverflow issue: https://stackoverflow.com/questions/75644447/autofocus-not-working-on-open-form-dialog-with-button-component-in-material-ui-v. I believe it is a “bug” in the restore-focus functionality in
FocusTrap– if I add thedisableRestoreFocusprop to theDialogthe auto focus works. When the incorrect behavior occurs, focus does go briefly to the text field but then returns immediately to the button.I believe the restore focus functionality is executing on open of the dialog. In strict mode with the dev react build, the FocusTrap component is being mounted twice, and the unmount after the first mount causes focus to be restored to the button.
I’m not seeing any easy way to fix this. It is correct for focus to be restored to the button during unmount, but I don’t think the dialog and text field DOM elements are actually being unmounted – it’s just a re-execution of their mount lifecycle. So the second mount brings focus back to the dialog, but the text field auto-focus functionality doesn’t re-execute since it was never removed/re-added to the DOM. This doesn’t seem to be as much a bug in
FocusTrapas it is an unfortunate side effect of the React 18 dev build strict mode behavior.Any updates on this? I can confirm this is still an issue as of
@mui/material 5.11.10.Adding an update for Dec 2023
Can still reproduce this TextField inside Dialog autoFocus behaviour on
"@mui/material": "^5.15.0""react": "^18.2.0"@SikandAlex’s solution works for me
disableRestoreFocuson the Dialog withautoFocuson the child TextFieldStrict Mode is enabled
I’m also using Vite tooling, but no special configurations here.
I ran into this same issue today. Maybe it’s related to https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state
You can swap the
<Textfield />for a normal<input />and get the same result.Here is the same sandbox without StrictMode, but with a double
setTimeoutthat trigger the modal to open/hide/open quickly. It also breaks the autofocus. https://codesandbox.io/s/wandering-dust-vptu4u?file=/src/index.jsSeems like using a timeout is a workaround. Updated sandbox, https://codesandbox.io/s/nostalgic-fermat-4eyjxr?file=/src/App.jsx