Bug: createRoot().render() is not fully synchronous unless wrapped in flushSync, unlike legacy ReactDOM.render #32811
Labels
Status: Unconfirmed
A potential issue that we haven't yet confirmed as a bug
React version:
18.2.0 (reproduced in latest 19.1 as well)
Summary
There is an open issue proposing documentation updates around the use of
flushSync
withcreateRoot().render()
to enforce synchronous rendering. However, since that issue has gone without feedback for several months, and given the core behavior observed, I suspect this may be an actual bug in React rather than just a documentation gap. I'm opening this issue here in the main React repository to clarify whether this behavior is intentional or not.Steps To Reproduce
createRoot(...).render(<App />)
.<App />
, log messages fromuseLayoutEffect
anduseEffect
.root.render()
call.createRoot(...).render(...)
(modern API)flushSync(() => root.render(...))
ReactDOM.render(...)
Link to code example: CodeSandbox
The current behavior
Using
createRoot(...).render(...)
without wrapping influshSync
, we observe that:useLayoutEffect
is emitted afterconsole.log("Post root.render")
, indicating the effect happens after the render call resolves.flushSync(() => root.render(...))
or legacyReactDOM.render(...)
,useLayoutEffect
is called before the post-render log.This suggests the modern root API allows post-render behavior to interleave with layout effects, even outside of explicitly opted-in concurrent features. This might violate expectations around synchronous behavior of the initial render.
The expected behavior
As @rickhanlonii noted in a related discussion, the initial render should be synchronous by default. If that’s the case, this behavior seems inconsistent.
createRoot(...).render(...)
should preserve layout effect timing consistency with legacyReactDOM.render(...)
, without needing to wrap influshSync
.createRoot(...).render(...)
may be async under certain conditions—even without concurrent features being enabled.The text was updated successfully, but these errors were encountered: