dillon1000/react

Commit

Fix: Treat incomplete tree as an error during recovery (#36911)

In `recoverFromConcurrentError`, there's logic to determine if the
latest render attempt resulted in another error or if it completed
successfully, by checking whether the exit status matches RootErrored.

The logic was incomplete because RootSuspendedAtTheShell is also
considered an errored state in this context. This can cause an
incomplete tree (i.e. one that unwinds without entering the complete
phase) to be mistaken for a complete one, leading to confusing errors.
An incomplete tree can never be committed because it's not guaranteed to
represent a coherent state.

An example of how this can manifest as a bug: in #33580, an error caught
by an error boundary triggers a synchronous recovery render. During that
render a parent component suspends on `use(thenable)` with no Suspense
boundary above it, so the tree unwinds to the shell instead of
completing. Because the incomplete tree is mistaken for a recovered one
and committed, the parent fiber becomes current with a truncated hook
list — only the hooks it rendered before suspending. On the next render
it calls the rest of its hooks and throws "Rendered more hooks than
during the previous render."

Fixes #33580.

Co-authored-by: Arunanshu Biswas
<[email protected]>

Co-authored-by: Arunanshu Biswas <[email protected]>
Browse files
Changed paths3 files
First-parent comparison
M packages/react-dom/src/__tests__/ReactDOMFizzShellHydration-test.js ModifiedM packages/react-reconciler/src/ReactFiberWorkLoop.js ModifiedM packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js Modified
Patch

Files changed

Rendering syntax-highlighted changes…