-
Notifications
You must be signed in to change notification settings - Fork 47k
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: Parent rerenders unnecessarily on Child-to-Parent setter call, while child rerenders only when changes occur. #28287
Comments
This is expected behavior. React queues state updates, and applies them in the render phase. If the new state value returned is identical to the previous value, React will bail out of the render for that component. If nothing else forced the component to render (its parent, other state updates, etc), then React will bail out of the render completely under the assumption that the output will be identical and there won't be any updates to apply. See my post A (Mostly) Complete Guide to React Rendering Behavior for details. |
But, it happens only when it rendered previously. This is a bit interesting. There might be some cases, useState's early bail-out doesn't work. (or, it can be said, it works, but some others trigger rendering?) FWIW, if you used |
@dai-shi yeah, I'm distinguishing between "bail out while rendering", vs the "early bailout while queuing the state update" behavior. (I know the early bailout exists, but I've tried to trace the code path a couple times and it's pretty confusing.) |
@abdelhakimrafik yep, that's not documented, but that matches the behavior I've seen in the past. |
This is actually documented in the
The reason this is happening in this cases is because, in order to bail out, we need to eagerly compute the last value the reducer returned with the new value the reducer returns, because reducers can close over props. In this case, when you first click "unchanged state" the last reducer rendered was This behavior might seem weird, but it was necessary to fix a bug where we would eagerly bail out in cases that would shouldn't, actually breaking the app.
There may be ways we could improve this in the future, which is why it's important to not depend on the behavior and ensure rendering a component is Pure. React needs to be able to control when, and how many times, a component is rendered for performance and UX improvements. For the latest information on which cases are supported and how React currently works, tests in the React repo are the best source. Closing as this behavior is expected and documented. |
React version: 18
Steps To Reproduce
Link to code example: https://codesandbox.io/p/sandbox/rendering-test-vts4v2?file=%2Fsrc%2FApp.js%3A3%2C20
The current behavior
The parent component rerenders even if the state remains unchanged.
When the parent component rerenders only due to unchanged state, the child component does not rerender.
If the value of state has been changed, the child components are rerendered.
The expected behavior
The parent component should not rerender if the state remains unchanged.
If the parent component rerenders, the child component should also rerender.
The text was updated successfully, but these errors were encountered: