diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index dbdb8542b9c13..abad6f9252501 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -125,7 +125,7 @@ import { addSubtreeSuspenseContext, setShallowSuspenseContext, } from './ReactFiberSuspenseContext'; -import {isShowingAnyFallbacks} from './ReactFiberSuspenseComponent'; +import {findFirstFallback} from './ReactFiberSuspenseComponent'; import { pushProvider, propagateContextChange, @@ -2000,7 +2000,7 @@ function findLastContentRow(firstChild: null | Fiber): null | Fiber { while (row !== null) { let currentRow = row.alternate; // New rows can't be content rows. - if (currentRow !== null && !isShowingAnyFallbacks(currentRow)) { + if (currentRow !== null && findFirstFallback(currentRow) === null) { lastContentRow = row; } row = row.sibling; @@ -2281,7 +2281,7 @@ function updateSuspenseListComponent( while (row !== null) { let currentRow = row.alternate; // New rows can't be content rows. - if (currentRow !== null && !isShowingAnyFallbacks(currentRow)) { + if (currentRow !== null && findFirstFallback(currentRow) === null) { // This is the beginning of the main content. workInProgress.child = row; break; diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.js b/packages/react-reconciler/src/ReactFiberCompleteWork.js index dd10799fc9616..9927f5d4c2e8d 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.js @@ -92,7 +92,7 @@ import { ForceSuspenseFallback, setDefaultShallowSuspenseContext, } from './ReactFiberSuspenseContext'; -import {isShowingAnyFallbacks} from './ReactFiberSuspenseComponent'; +import {findFirstFallback} from './ReactFiberSuspenseComponent'; import { isContextProvider as isLegacyContextProvider, popContext as popLegacyContext, @@ -1061,7 +1061,8 @@ function completeWork( } else { // Append the rendered row to the child list. if (!didSuspendAlready) { - if (isShowingAnyFallbacks(renderedTail)) { + let fallback = findFirstFallback(renderedTail); + if (fallback !== null) { workInProgress.effectTag |= DidCapture; didSuspendAlready = true; cutOffTailIfNeeded(renderState, true); @@ -1072,9 +1073,11 @@ function completeWork( ) { // We need to delete the row we just rendered. // Ensure we transfer the update queue to the parent. - // TODO: This just reuses the code from the other path but could - // be optimized better. - hasSuspendedChildrenAndNewContent(workInProgress, renderedTail); + let fallbackThennables = fallback.updateQueue; + if (fallbackThennables !== null) { + workInProgress.updateQueue = fallbackThennables; + workInProgress.effectTag |= Update; + } // Reset the effect list to what it w as before we rendered this // child. The nested children have already appended themselves. let lastEffect = (workInProgress.lastEffect = diff --git a/packages/react-reconciler/src/ReactFiberSuspenseComponent.js b/packages/react-reconciler/src/ReactFiberSuspenseComponent.js index 9f828872f8c34..08e32c1088f03 100644 --- a/packages/react-reconciler/src/ReactFiberSuspenseComponent.js +++ b/packages/react-reconciler/src/ReactFiberSuspenseComponent.js @@ -61,13 +61,13 @@ export function shouldCaptureSuspense( return true; } -export function isShowingAnyFallbacks(row: Fiber): boolean { +export function findFirstFallback(row: Fiber): null | Fiber { let node = row; while (node !== null) { if (node.tag === SuspenseComponent) { const state: SuspenseState | null = node.memoizedState; if (state !== null) { - return true; + return node; } } else if (node.child !== null) { node.child.return = node; @@ -75,16 +75,16 @@ export function isShowingAnyFallbacks(row: Fiber): boolean { continue; } if (node === row) { - return false; + return null; } while (node.sibling === null) { if (node.return === null || node.return === row) { - return false; + return null; } node = node.return; } node.sibling.return = node.return; node = node.sibling; } - return false; + return null; }