dillon1000/react

Commit

[suspense] Avoid double commit by re-rendering immediately and reusing primary children (#14083)

* Avoid double commit by re-rendering immediately and reusing children

To support Suspense outside of concurrent mode, any component that
starts rendering must commit synchronously without being interrupted.
This means normal path, where we unwind the stack and try again from the
nearest Suspense boundary, won't work.

We used to have a special case where we commit the suspended tree in an
incomplete state. Then, in a subsequent commit, we re-render using the
fallback.

The first part — committing an incomplete tree — hasn't changed with
this PR. But I've changed the second part — now we render the fallback
children immediately, within the same commit.

* Add a failing test for remounting fallback in sync mode

* Add failing test for stuck Suspense fallback

* Toggle visibility of Suspense children in mutation phase, not layout

If parent reads visibility of children in a lifecycle, they should have
already updated.
Browse files
Changed paths10 files
First-parent comparison
M packages/react-dom/src/__tests__/ReactDOMSuspensePlaceholder-test.internal.js ModifiedM packages/react-reconciler/src/ReactFiberBeginWork.js ModifiedM packages/react-reconciler/src/ReactFiberCommitWork.js ModifiedM packages/react-reconciler/src/ReactFiberCompleteWork.js ModifiedM packages/react-reconciler/src/ReactFiberScheduler.js ModifiedM packages/react-reconciler/src/ReactFiberSuspenseComponent.js ModifiedM packages/react-reconciler/src/ReactFiberUnwindWork.js ModifiedM packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js ModifiedM packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js ModifiedM packages/react/src/__tests__/ReactProfiler-test.internal.js Modified
Patch

Files changed

Rendering syntax-highlighted changes…