dillon1000/react
Commit
Browse files [Bugfix] Prevent infinite update loop caused by a synchronous update in a passive effect (#22277)
* Add test that triggers infinite update loop In 18, passive effects are flushed synchronously if they are the result of a synchronous update. We have a guard for infinite update loops that occur in the layout phase, but it doesn't currently work for synchronous updates from a passive effect. The reason this probably hasn't come up yet is because synchronous updates inside the passive effect phase are relatively rare: you either have to imperatively dispatch a discrete event, like `el.focus`, or you have to call `ReactDOM.flushSync`, which triggers a warning. (In general, updates inside a passive effect are not encouraged.) I discovered this because `useSyncExternalStore` does sometimes trigger updates inside the passive effect phase. This commit adds a failing test to prove the issue exists. I will fix it in the next commit. * Fix failing test added in previous commit The way we detect a "nested update" is if there's synchronous work remaining at the end of the commit phase. Currently this check happens before we synchronously flush the passive effects. I moved it to after the effects are fired, so that it detects whether synchronous work was scheduled in that phase.
Changed paths3 files
First-parent comparisonpackages/react-dom/src/__tests__/ReactUpdates-test.js ModifiedM packages/react-reconciler/src/ReactFiberWorkLoop.new.js ModifiedM packages/react-reconciler/src/ReactFiberWorkLoop.old.js ModifiedPatch
Files changed
Rendering syntax-highlighted changes…