I’m writing a somewhat complex app with React and Redux, and I have a situation where clicking a button dispatches an action that creates a new DOM element in a completely different part of the app and I want this new DOM element to be focused. I’m wondering what’s the best way to do it.
I managed to make it work like this:
const handleClick = () => {
ReactDOM.flushSync(() => {
dispatch(createNewElement(id));
});
document.getElementById(id).focus();
};
I'm using regular DOM ids to identify the element to focus and the (almost undocumented) flushSync function to make sure that it is actually present in the DOM when selecting it.
I cannot use refs because the new element is in a completely different component. I cannot use autoFocus because those elements can also be created in ways that should not be autofocused and I don’t want my HTML to be littered with obsolete autofocus's. I don’t want to put the focused state in the Redux store because it will be a nightmare to maintain properly.
Instead of flushSync I could also wrap the .focus in a setTimeout(…, 0). It seems to work but I’m not entirely convinced that the element is guaranteed to be present by the time the timeout runs (unlike with flushSync).
Is this a legitimate use of ReactDOM.flushSync? Is there another simpler way to do it?