Skip to content

Commit

Permalink
Fix continuation bug (#31434)
Browse files Browse the repository at this point in the history
## Overview

In `scheduleTaskForRootDuringMicrotask` we clear `root.callbackNode` if
the work loop is [suspended waiting on
data](https://github.com/facebook/react/blob/ac3ca097aeecae8fe3ec7f9b286307a923676518/packages/react-reconciler/src/ReactFiberRootScheduler.js#L338).

But we don't null check `root.callbackNode` before returning a
continuation in `performWorkOnRootViaSchedulerTask` where
`scheduleTaskForRootDuringMicrotask` is synchronously called, causing an
infinite loop when the only thing in the queue is something suspended
waiting on data.

This essentially restores the behavior from here:
https://github.com/facebook/react/pull/26328/files#diff-72ff2175ae3569037f0b16802a41b0cda2b2d66bb97f2bda78ed8445ed487b58L1168

Found by investigating the failures for
#31417

## TODO
- add a test

---------

Co-authored-by: Joe Savona <[email protected]>
  • Loading branch information
rickhanlonii and josephsavona authored Nov 11, 2024
1 parent ed15d50 commit b836de6
Show file tree
Hide file tree
Showing 3 changed files with 681 additions and 19 deletions.
2 changes: 1 addition & 1 deletion packages/react-reconciler/src/ReactFiberRootScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ function performWorkOnRootViaSchedulerTask(
// only safe to do because we know we're at the end of the browser task.
// So although it's not an actual microtask, it might as well be.
scheduleTaskForRootDuringMicrotask(root, now());
if (root.callbackNode === originalCallbackNode) {
if (root.callbackNode != null && root.callbackNode === originalCallbackNode) {
// The task node scheduled for this root is the same one that's
// currently executed. Need to return a continuation.
return performWorkOnRootViaSchedulerTask.bind(null, root);
Expand Down
Loading

0 comments on commit b836de6

Please sign in to comment.