dillon1000/react

Commit

Suspending outside of strict trees and async trees (#13098)

We can support components that suspend outside of an async mode tree
by immediately committing their placeholders.

In strict mode, the Timeout acts effectively like an error boundary.
Within a single render pass, we unwind to the nearest Timeout and
re-render the placeholder view.

Outside of strict mode, it's not safe to unwind and re-render the
siblings without committing. (Technically, this is true of error
boundaries, too, though probably not a huge deal, since we don't support
using error boundaries for control flow (yet, at least)). We need to be
clever. What we do is pretend the suspended component rendered null.*
There's no unwinding. The siblings commit like normal.

Then, in the commit phase, schedule an update on the Timeout to
synchronously re-render the placeholder. Although this requires an extra
commit, it will not be observable. And because the siblings were not
blocked from committing, they don't have to be strict mode compatible.

Another caveat is that if a component suspends during an async render,
but it's captured by a non-async Timeout, we need to revert to sync
mode. In other words, if any non-async component renders, the entire
tree must complete and commit without yielding.

* The downside of rendering null is that the existing children will be
deleted. We should hide them instead. I'll work on this in a follow-up.
Browse files
Changed paths8 files
First-parent comparison
M packages/react-noop-renderer/src/createReactNoop.js ModifiedM packages/react-reconciler/src/ReactFiber.js ModifiedM packages/react-reconciler/src/ReactFiberBeginWork.js ModifiedM packages/react-reconciler/src/ReactFiberCommitWork.js ModifiedM packages/react-reconciler/src/ReactFiberScheduler.js ModifiedM packages/react-reconciler/src/ReactFiberUnwindWork.js ModifiedM packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js ModifiedM packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap Modified
Patch

Files changed

Rendering syntax-highlighted changes…