-
Notifications
You must be signed in to change notification settings - Fork 46.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: State updates in ResizeObserver callbacks are applied after paint and cause visual glitches #24331
Comments
I don’t think there’s a way for us to detect this so flushSync is the right answer. Unless we get a lot more aggressive and start overriding built-ins. |
Any further insight on whether this is a bug on React's side which any chances of being handled? Note that flushSync comes with performance implications (even more so if having to wrap it in |
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment! |
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you! |
same here |
React version: 18
When a state value gets updated in a
ResizeObserver
callback, I believe that React should make sure that the DOM is up-to-date before the next paint. Otherwise, if we are usingResizeObserver
to do some visual changes to some part(s) of the app as soon as some element resizes (which seems like a reasonable assumption), it can create visual glitches.It worked fine in React 17, but in React 18 the state updates seem to be deferred to a later time (unless
flushSync
is used). This is most likely due to the "batch state updates" change in React 18.Steps To Reproduce
In the example below we use a
ResizeObserver
to make sure that the width of the blue div always matches exactly the width of the grey textarea under it.shouldUseFlushSync
flag in the code and quickly resize the grey textarea again. Notice that they now stay perfectly in sync, the glitch is gone.Link to code example: https://codesandbox.io/s/amazing-montalcini-j6lz46?file=/src/App.js (tested in Chrome on Linux)
(it is probably more visible on a slow computer, you can try enabling CPU throttling if you cannot see it)
The current behavior
We need to use
flushSync
in order for the app to work without glitches.The expected behavior
Given that it is probably pretty common to use
ResizeObserver
to make sure that some part of the app stays visually in sync with some other part of the app, I would expect React to guarantee that updates triggered in aResizeObserver
callback will be applied before the browser gets the chance to paint the resized element, and without expecting the developer to use the somewhat obscureflushSync
method.Related
I could only find one related issue: #21119, but it is about batching several updates coming from the same callback. It's perfectly fine to batch several updates coming from the same
ResizeObserver
callback (or even from several such) as long as they are guaranteed to be applied before the resized element is painted again by the browser.The text was updated successfully, but these errors were encountered: