Skip to content
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

Closed
guillaumebrunerie opened this issue Apr 10, 2022 · 5 comments
Labels
Resolution: Stale Automatically closed due to inactivity Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@guillaumebrunerie
Copy link

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 using ResizeObserver 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.

  1. Quickly resize the grey textarea. Notice that the width of the blue div lags behind.
  2. Turn on the 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 a ResizeObserver callback will be applied before the browser gets the chance to paint the resized element, and without expecting the developer to use the somewhat obscure flushSync 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.

@guillaumebrunerie guillaumebrunerie added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Apr 10, 2022
@gaearon
Copy link
Collaborator

gaearon commented Apr 10, 2022

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.

@jperals
Copy link

jperals commented Jul 20, 2023

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 queueMicrotask when calling it in a lifecycle hook) so I'm a bit hesitant to adopt that workaround.

Copy link

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!

@github-actions github-actions bot added the Resolution: Stale Automatically closed due to inactivity label Apr 10, 2024
Copy link

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!

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 17, 2024
@AAblaev
Copy link

AAblaev commented Aug 26, 2024

same here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Stale Automatically closed due to inactivity Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

4 participants