-
Notifications
You must be signed in to change notification settings - Fork 47.5k
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
React 18: useEffect different behaviour compare to v17 in specific cases #23090
Comments
It's an interesting case, but the thing is, the code is definitely incorrect, you can't use external mutable values as |
@vkurchatkin Hi! My example could be too simple, here's almost the same example, but with
|
This comment has been minimized.
This comment has been minimized.
@vkurchatkin yes, the simplified code itself is incorrect, but I feel extremely curious as to why this happens. I mean, the component is re-rendering, and the value of the deps array for |
The effect is firing with 18.1: https://codesandbox.io/s/react-bug-version-3-forked-dofmh8?file=/src/example.js @dmitryKochergin Could you confirm that this is now fixed? |
@eps1lon Yes, with the new root API it works fine. |
I don't understand what the bug with the old root API is? Could you point me again to a CodeSandbox with the latest version of React and the old root API and explain what you see and what you expected instead? |
@eps1lon here's a codesandbox with react 18.1 which still shows the bug. Bug: If you go to ReactDOM.render(
<StrictMode>
<Example />
</StrictMode>,
rootElement
); by const root = ReactDOM.createRoot(rootElement);
root.render(<StrictMode><Example /></StrictMode>); you'll see the expected behavior (that is, |
I've encountered this behavior change as well. I'm not sure how to create a reproduction case out of our code base, but essentially what I see is that given the following logic: const value = useCustomHook()
console.log("value is now:", value)
useEffect(() => {
console.log("effect is running for value:", value)
}, [value]) Then the following logs can be observed:
Essentially, even if the component is clearly re-rendering multiple times (the re-render is triggered via a It's almost as if the first render where the If the repro cases in this issue aren't enough, I can take a stab at creating one from our code base but my first attempt did not reproduce this bug. This behavior is observed using either API to mount React. |
Okay so I did end up managing to reproduce this. Basically if you synchronously end up in a flow like the following, a component will re-render with new state, but not trigger effects, which I think is a bug:
Here's the small repro: https://codesandbox.io/s/funny-galois-1wr2ib?file=/src/App.js To test the repro you'd follow these steps:
|
Hi!
In this issue to react-query repo we found some strange useEffect behaviour.
Here's examples:
react 17
react 18 with old root api
Just click "rerender" button and see that there's no effect firing.
But in react 18 with the new root API it works fine:
codesandbox
I tried to explain it like that:
So, is this right explanation for what is going on there?
And I guess, the main question, why does this example work fine when the new root api is used?
Does it mean that with the new root api (and with concurrent mode) useEffect compare deps only with those from the last previous render that was committed to the DOM?
Thanks!
The text was updated successfully, but these errors were encountered: