-
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: Nested setState and unstable_batchedUpdates (are they ignored?) #17970
Comments
The sandbox isn't actually testing the behavior you think it is. First, React already wraps all event handlers in Second, either way, that button click event handler is only queueing one state update, not multiple, so there's no change in behavior. Third, each of those child components is adding an additional state update in the commit phase, but that's after the On the other hand, what React-Redux does is call |
Sorry I do not think so. React redux call notifynestedsub under uselayouteffecct that is exact the problem of this issue. Open profile of this original nested redux update with connect. Anyway it would be useful to know from react core team if this is an expected behavior, setStates sync in uselayouteffecct does not get batched, and there are many commit even if user will not see them due to sync. |
Mark is right that |
@bvaughn: just to confirm something: If a component tree has something like this: function Parent() {
useLayoutEffect(() => {
ReactDOM.unstable_batchedUpdates( () => {
eventEmitter.trigger("update");
});
});
// return some nested child components
}
function Child() {
const [, forceUpdate] = useReducer(s => s + 1, 0);
useLayoutEffect( () => {
eventEmitter.on("update", forceUpdate);
return () => eventEmitter.off("update", forceUpdate);
}, []);
} I would expect that when the parent component re-renders, all nested children would queue updates due to the event emitter triggering. But, because the calls to Is that a correct summary? |
just to confirm the call stack of this issue: ReactDOM.unstable_batchedUpdates(() => {
setCount1(c => c + 1);
// ....
useLayoutEffect1(()=>{
setCount2(c => c + 1);
// ....
useLayoutEffect2(()=>{
setCount3(c => c + 1);
// ....
})
})
}); so the batches are interrupted @ first useLayoutEffect? (even if next calls are sync) ? |
@markerikson Yes. @salvoravida That is not the call stack. The function you pass to |
@bvaughn so there is no way to batch all updates from an external source emitted in top down in a single commit. useMutableSource will handle this case? |
@salvoravida : The issue for React-Redux specifically is that we can't run the If those weren't a point of concern, we could just go ahead and let all components subscribe to the root So, for our current implementation, we must have multiple commits to handle things correctly working down the tree. |
@markerikson yes i know the issues, and i agree with you. What i exspected is that using LayoutEffects handlers that are sync with renders, and batched updates, multiple sync commit where merged to one. Maybe we see 4 commit into Profiler, but as they are sync, they are de-facto merged as browser will (not paint/user will not see) them until render-sync finished @bvaughn is correct? |
Yeah. In our case, they're separate render passes, all run synchronously during the commit phase. Because they're run sync, the browser won't repaint until after the commit phase is complete. |
This sounds misleading 😄 If the Profiler reports 4 commits, there were 4 commits- (which means e.g. 4 DOM mutations)- even if there was no painting between them. I'm going to go ahead and close this issue since I think the original question has been answered! |
Nested setState and unstable_batchedUpdates (are them ignored?)
React version: 16.12
Steps To Reproduce
https://codesandbox.io/s/batchedupdates-uselayouteffect-evj8s
open profile after click, you will see 3 commit.
it seems that even if we use unstable_batchedUpdates, nested setStates called on
didUpdate/layouteffect do not get batched.
The text was updated successfully, but these errors were encountered: