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: useEffect runs before DOM changes are painted #29584

Closed
rachitiitr opened this issue May 24, 2024 · 5 comments
Closed

Bug: useEffect runs before DOM changes are painted #29584

rachitiitr opened this issue May 24, 2024 · 5 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@rachitiitr
Copy link

rachitiitr commented May 24, 2024

React version: ^18.0.0

Steps To Reproduce

  1. Refer the attached codesandbox link
  2. Consider the click that leads to a winner in tic-tac-toe game
  3. We get an alert that a player has won, however, the board is not yet painted on the browser.
  4. The expectation of browser painting the click first followed by the effect execution is broken.

Video Link explaining the bug:
https://www.youtube.com/watch?v=v8KLOx_Mm48

Link to code example:
https://codesandbox.io/p/sandbox/tic-tac-toe-gpjn57

The current behavior

The expectation of browser painting the click first followed by the effect execution is broken.
We get an alert first, then the updated board is painted by browser.

The expected behavior

We expect the board to update first, then the effect should run which should cause the alert.

@rachitiitr rachitiitr added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label May 24, 2024
@rickhanlonii
Copy link
Member

This is expected. When the update is the result of a user event like click, React may fire the effect synchronously before the browser paints.

To fix this case, you can move the check to a timeout.

See Caveats: https://react.dev/reference/react/useEffect#caveats

@rachitiitr
Copy link
Author

rachitiitr commented May 24, 2024

This is expected. When the update is the result of a user event like click, React may fire the effect synchronously before the browser paints.

To fix this case, you can move the check to a timeout.

See Caveats: https://react.dev/reference/react/useEffect#caveats

Thanks @rickhanlonii for taking the time to read my issue and reply back.

This is what I found in the link you referred above -

  • If your Effect wasn’t caused by an interaction (like a click), React will generally let the browser paint the updated screen first before running your Effect.
  • Even if your Effect was caused by an interaction (like a click), the browser may repaint the screen before processing the state updates inside your Effect.

^ This is written in the caveats section of the documentation.

Both points profess the idea that React prioritises browser painting before running the effects.
So, it kind of makes me believe React will let the browser to paint first. It's not very obvious that React can fire the effect synchronously before the browser paints.

  1. Can we please get more clarity on how is this decision made?
  2. Do you think it makes sense to articulate this possibility as a new point in the caveats section?

@rickhanlonii
Copy link
Member

rickhanlonii commented May 24, 2024

Here's a deep dive on the change reactwg/react-18#128

@rickhanlonii
Copy link
Member

Clarified the docs in reactjs/react.dev#6910

@Md-124
Copy link

Md-124 commented May 29, 2024

@rachitiitr see this reactjs/react.dev#6207

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

No branches or pull requests

3 participants