diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index 521a75d11dcb7..8bf7e78bc2c77 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -236,7 +236,7 @@ import { pushRootCachePool, CacheContext, getSuspendedCachePool, - restoreSpawnedCachePool, + pushSpawnedCachePool, getOffscreenDeferredCachePool, } from './ReactFiberCacheComponent.new'; import {createCapturedValue} from './ReactCapturedValue'; @@ -637,11 +637,6 @@ function updateOffscreenComponent( const prevState: OffscreenState | null = current !== null ? current.memoizedState : null; - // If this is not null, this is a cache pool that was carried over from the - // previous render. We will push this to the cache pool context so that we can - // resume in-flight requests. - let spawnedCachePool: SpawnedCachePool | null = null; - if ( nextProps.mode === 'hidden' || nextProps.mode === 'unstable-defer-without-hiding' @@ -654,8 +649,16 @@ function updateOffscreenComponent( cachePool: null, }; workInProgress.memoizedState = nextState; + if (enableCache) { + // push the cache pool even though we're going to bail out + // because otherwise there'd be a context mismatch + if (current !== null) { + pushSpawnedCachePool(workInProgress, null); + } + } pushRenderLanes(workInProgress, renderLanes); } else if (!includesSomeLane(renderLanes, (OffscreenLane: Lane))) { + let spawnedCachePool: SpawnedCachePool | null = null; // We're hidden, and we're not rendering at Offscreen. We will bail out // and resume this tree later. let nextBaseLanes; @@ -665,9 +668,6 @@ function updateOffscreenComponent( if (enableCache) { // Save the cache pool so we can resume later. spawnedCachePool = getOffscreenDeferredCachePool(); - // We don't need to push to the cache pool because we're about to - // bail out. There won't be a context mismatch because we only pop - // the cache pool if `updateQueue` is non-null. } } else { nextBaseLanes = renderLanes; @@ -683,6 +683,14 @@ function updateOffscreenComponent( }; workInProgress.memoizedState = nextState; workInProgress.updateQueue = null; + if (enableCache) { + // push the cache pool even though we're going to bail out + // because otherwise there'd be a context mismatch + if (current !== null) { + pushSpawnedCachePool(workInProgress, null); + } + } + // We're about to bail out, but we need to push this to the stack anyway // to avoid a push/pop misalignment. pushRenderLanes(workInProgress, nextBaseLanes); @@ -703,19 +711,6 @@ function updateOffscreenComponent( // This is the second render. The surrounding visible content has already // committed. Now we resume rendering the hidden tree. - if (enableCache && prevState !== null) { - // If the render that spawned this one accessed the cache pool, resume - // using the same cache. Unless the parent changed, since that means - // there was a refresh. - const prevCachePool = prevState.cachePool; - if (prevCachePool !== null) { - spawnedCachePool = restoreSpawnedCachePool( - workInProgress, - prevCachePool, - ); - } - } - // Rendering at offscreen, so we can clear the base lanes. const nextState: OffscreenState = { baseLanes: NoLanes, @@ -725,6 +720,14 @@ function updateOffscreenComponent( // Push the lanes that were skipped when we bailed out. const subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes; + if (enableCache && current !== null) { + // If the render that spawned this one accessed the cache pool, resume + // using the same cache. Unless the parent changed, since that means + // there was a refresh. + const prevCachePool = prevState !== null ? prevState.cachePool : null; + pushSpawnedCachePool(workInProgress, prevCachePool); + } + pushRenderLanes(workInProgress, subtreeRenderLanes); } } else { @@ -740,12 +743,7 @@ function updateOffscreenComponent( // using the same cache. Unless the parent changed, since that means // there was a refresh. const prevCachePool = prevState.cachePool; - if (prevCachePool !== null) { - spawnedCachePool = restoreSpawnedCachePool( - workInProgress, - prevCachePool, - ); - } + pushSpawnedCachePool(workInProgress, prevCachePool); } // Since we're not hidden anymore, reset the state @@ -755,16 +753,19 @@ function updateOffscreenComponent( // special to do. Need to push to the stack regardless, though, to avoid // a push/pop misalignment. subtreeRenderLanes = renderLanes; + + if (enableCache) { + // If the render that spawned this one accessed the cache pool, resume + // using the same cache. Unless the parent changed, since that means + // there was a refresh. + if (current !== null) { + pushSpawnedCachePool(workInProgress, null); + } + } } pushRenderLanes(workInProgress, subtreeRenderLanes); } - if (enableCache) { - // If we have a cache pool from a previous render attempt, then this will be - // non-null. We use this to infer whether to push/pop the cache context. - workInProgress.updateQueue = spawnedCachePool; - } - if (enablePersistentOffscreenHostContainer && supportsPersistence) { // In persistent mode, the offscreen children are wrapped in a host node. // TODO: Optimize this to use the OffscreenComponent fiber instead of @@ -2074,6 +2075,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { const nextPrimaryChildren = nextProps.children; const nextFallbackChildren = nextProps.fallback; + if (showFallback) { const fallbackFragment = mountSuspenseFallbackChildren( workInProgress, diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.old.js b/packages/react-reconciler/src/ReactFiberBeginWork.old.js index 471bb11d941da..1febc036f7219 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.old.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.old.js @@ -236,7 +236,7 @@ import { pushRootCachePool, CacheContext, getSuspendedCachePool, - restoreSpawnedCachePool, + pushSpawnedCachePool, getOffscreenDeferredCachePool, } from './ReactFiberCacheComponent.old'; import {createCapturedValue} from './ReactCapturedValue'; @@ -637,11 +637,6 @@ function updateOffscreenComponent( const prevState: OffscreenState | null = current !== null ? current.memoizedState : null; - // If this is not null, this is a cache pool that was carried over from the - // previous render. We will push this to the cache pool context so that we can - // resume in-flight requests. - let spawnedCachePool: SpawnedCachePool | null = null; - if ( nextProps.mode === 'hidden' || nextProps.mode === 'unstable-defer-without-hiding' @@ -654,8 +649,16 @@ function updateOffscreenComponent( cachePool: null, }; workInProgress.memoizedState = nextState; + if (enableCache) { + // push the cache pool even though we're going to bail out + // because otherwise there'd be a context mismatch + if (current !== null) { + pushSpawnedCachePool(workInProgress, null); + } + } pushRenderLanes(workInProgress, renderLanes); } else if (!includesSomeLane(renderLanes, (OffscreenLane: Lane))) { + let spawnedCachePool: SpawnedCachePool | null = null; // We're hidden, and we're not rendering at Offscreen. We will bail out // and resume this tree later. let nextBaseLanes; @@ -665,9 +668,6 @@ function updateOffscreenComponent( if (enableCache) { // Save the cache pool so we can resume later. spawnedCachePool = getOffscreenDeferredCachePool(); - // We don't need to push to the cache pool because we're about to - // bail out. There won't be a context mismatch because we only pop - // the cache pool if `updateQueue` is non-null. } } else { nextBaseLanes = renderLanes; @@ -683,6 +683,14 @@ function updateOffscreenComponent( }; workInProgress.memoizedState = nextState; workInProgress.updateQueue = null; + if (enableCache) { + // push the cache pool even though we're going to bail out + // because otherwise there'd be a context mismatch + if (current !== null) { + pushSpawnedCachePool(workInProgress, null); + } + } + // We're about to bail out, but we need to push this to the stack anyway // to avoid a push/pop misalignment. pushRenderLanes(workInProgress, nextBaseLanes); @@ -703,19 +711,6 @@ function updateOffscreenComponent( // This is the second render. The surrounding visible content has already // committed. Now we resume rendering the hidden tree. - if (enableCache && prevState !== null) { - // If the render that spawned this one accessed the cache pool, resume - // using the same cache. Unless the parent changed, since that means - // there was a refresh. - const prevCachePool = prevState.cachePool; - if (prevCachePool !== null) { - spawnedCachePool = restoreSpawnedCachePool( - workInProgress, - prevCachePool, - ); - } - } - // Rendering at offscreen, so we can clear the base lanes. const nextState: OffscreenState = { baseLanes: NoLanes, @@ -725,6 +720,14 @@ function updateOffscreenComponent( // Push the lanes that were skipped when we bailed out. const subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes; + if (enableCache && current !== null) { + // If the render that spawned this one accessed the cache pool, resume + // using the same cache. Unless the parent changed, since that means + // there was a refresh. + const prevCachePool = prevState !== null ? prevState.cachePool : null; + pushSpawnedCachePool(workInProgress, prevCachePool); + } + pushRenderLanes(workInProgress, subtreeRenderLanes); } } else { @@ -740,12 +743,7 @@ function updateOffscreenComponent( // using the same cache. Unless the parent changed, since that means // there was a refresh. const prevCachePool = prevState.cachePool; - if (prevCachePool !== null) { - spawnedCachePool = restoreSpawnedCachePool( - workInProgress, - prevCachePool, - ); - } + pushSpawnedCachePool(workInProgress, prevCachePool); } // Since we're not hidden anymore, reset the state @@ -755,16 +753,19 @@ function updateOffscreenComponent( // special to do. Need to push to the stack regardless, though, to avoid // a push/pop misalignment. subtreeRenderLanes = renderLanes; + + if (enableCache) { + // If the render that spawned this one accessed the cache pool, resume + // using the same cache. Unless the parent changed, since that means + // there was a refresh. + if (current !== null) { + pushSpawnedCachePool(workInProgress, null); + } + } } pushRenderLanes(workInProgress, subtreeRenderLanes); } - if (enableCache) { - // If we have a cache pool from a previous render attempt, then this will be - // non-null. We use this to infer whether to push/pop the cache context. - workInProgress.updateQueue = spawnedCachePool; - } - if (enablePersistentOffscreenHostContainer && supportsPersistence) { // In persistent mode, the offscreen children are wrapped in a host node. // TODO: Optimize this to use the OffscreenComponent fiber instead of @@ -2074,6 +2075,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { const nextPrimaryChildren = nextProps.children; const nextFallbackChildren = nextProps.fallback; + if (showFallback) { const fallbackFragment = mountSuspenseFallbackChildren( workInProgress, diff --git a/packages/react-reconciler/src/ReactFiberCacheComponent.new.js b/packages/react-reconciler/src/ReactFiberCacheComponent.new.js index cf851af6e3de3..3d1db8124b692 100644 --- a/packages/react-reconciler/src/ReactFiberCacheComponent.new.js +++ b/packages/react-reconciler/src/ReactFiberCacheComponent.new.js @@ -198,29 +198,18 @@ export function popRootCachePool(root: FiberRoot, renderLanes: Lanes) { // code organization purposes in case that changes. } -export function restoreSpawnedCachePool( +export function pushSpawnedCachePool( offscreenWorkInProgress: Fiber, - prevCachePool: SpawnedCachePool, -): SpawnedCachePool | null { + prevCachePool: SpawnedCachePool | null, +): void { if (!enableCache) { - return (null: any); + return; } - const nextParentCache = isPrimaryRenderer - ? CacheContext._currentValue - : CacheContext._currentValue2; - if (nextParentCache !== prevCachePool.parent) { - // There was a refresh. Don't bother restoring anything since the refresh - // will override it. - return null; + + if (prevCachePool === null) { + push(resumedCache, resumedCache.current, offscreenWorkInProgress); } else { - // No refresh. Resume with the previous cache. New Cache boundaries in the - // subtree use this one instead of requesting a fresh one (see - // peekCacheFromPool). push(resumedCache, prevCachePool.pool, offscreenWorkInProgress); - - // Return the cache pool to signal that we did in fact push it. We will - // assign this to the field on the fiber so we know to pop the context. - return prevCachePool; } } @@ -228,6 +217,7 @@ export function popCachePool(workInProgress: Fiber) { if (!enableCache) { return; } + pop(resumedCache, workInProgress); } diff --git a/packages/react-reconciler/src/ReactFiberCacheComponent.old.js b/packages/react-reconciler/src/ReactFiberCacheComponent.old.js index 692dba781302e..74dc9a449a507 100644 --- a/packages/react-reconciler/src/ReactFiberCacheComponent.old.js +++ b/packages/react-reconciler/src/ReactFiberCacheComponent.old.js @@ -198,29 +198,18 @@ export function popRootCachePool(root: FiberRoot, renderLanes: Lanes) { // code organization purposes in case that changes. } -export function restoreSpawnedCachePool( +export function pushSpawnedCachePool( offscreenWorkInProgress: Fiber, - prevCachePool: SpawnedCachePool, -): SpawnedCachePool | null { + prevCachePool: SpawnedCachePool | null, +): void { if (!enableCache) { - return (null: any); + return; } - const nextParentCache = isPrimaryRenderer - ? CacheContext._currentValue - : CacheContext._currentValue2; - if (nextParentCache !== prevCachePool.parent) { - // There was a refresh. Don't bother restoring anything since the refresh - // will override it. - return null; + + if (prevCachePool === null) { + push(resumedCache, resumedCache.current, offscreenWorkInProgress); } else { - // No refresh. Resume with the previous cache. New Cache boundaries in the - // subtree use this one instead of requesting a fresh one (see - // peekCacheFromPool). push(resumedCache, prevCachePool.pool, offscreenWorkInProgress); - - // Return the cache pool to signal that we did in fact push it. We will - // assign this to the field on the fiber so we know to pop the context. - return prevCachePool; } } @@ -228,6 +217,7 @@ export function popCachePool(workInProgress: Fiber) { if (!enableCache) { return; } + pop(resumedCache, workInProgress); } diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js index 39f724c76df92..bb01e2b8a2a26 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.new.js @@ -28,7 +28,7 @@ import type { } from './ReactFiberSuspenseComponent.new'; import type {SuspenseContext} from './ReactFiberSuspenseContext.new'; import type {OffscreenState} from './ReactFiberOffscreenComponent'; -import type {Cache, SpawnedCachePool} from './ReactFiberCacheComponent.new'; +import type {Cache} from './ReactFiberCacheComponent.new'; import { enableClientRenderFallbackOnHydrationMismatch, enableSuspenseAvoidThisFallback, @@ -865,8 +865,8 @@ function completeWork( popRootCachePool(fiberRoot, renderLanes); let previousCache: Cache | null = null; - if (workInProgress.alternate !== null) { - previousCache = workInProgress.alternate.memoizedState.cache; + if (current !== null) { + previousCache = current.memoizedState.cache; } const cache: Cache = workInProgress.memoizedState.cache; if (cache !== previousCache) { @@ -1533,11 +1533,11 @@ function completeWork( if (enableCache) { let previousCache: Cache | null = null; if ( - workInProgress.alternate !== null && - workInProgress.alternate.memoizedState !== null && - workInProgress.alternate.memoizedState.cachePool !== null + current !== null && + current.memoizedState !== null && + current.memoizedState.cachePool !== null ) { - previousCache = workInProgress.alternate.memoizedState.cachePool.pool; + previousCache = current.memoizedState.cachePool.pool; } let cache: Cache | null = null; if ( @@ -1550,8 +1550,7 @@ function completeWork( // Run passive effects to retain/release the cache. workInProgress.flags |= Passive; } - const spawnedCachePool: SpawnedCachePool | null = (workInProgress.updateQueue: any); - if (spawnedCachePool !== null) { + if (current !== null) { popCachePool(workInProgress); } } @@ -1561,8 +1560,8 @@ function completeWork( case CacheComponent: { if (enableCache) { let previousCache: Cache | null = null; - if (workInProgress.alternate !== null) { - previousCache = workInProgress.alternate.memoizedState.cache; + if (current !== null) { + previousCache = current.memoizedState.cache; } const cache: Cache = workInProgress.memoizedState.cache; if (cache !== previousCache) { diff --git a/packages/react-reconciler/src/ReactFiberCompleteWork.old.js b/packages/react-reconciler/src/ReactFiberCompleteWork.old.js index c7baf36d16c47..0d9de679a0f43 100644 --- a/packages/react-reconciler/src/ReactFiberCompleteWork.old.js +++ b/packages/react-reconciler/src/ReactFiberCompleteWork.old.js @@ -28,7 +28,7 @@ import type { } from './ReactFiberSuspenseComponent.old'; import type {SuspenseContext} from './ReactFiberSuspenseContext.old'; import type {OffscreenState} from './ReactFiberOffscreenComponent'; -import type {Cache, SpawnedCachePool} from './ReactFiberCacheComponent.old'; +import type {Cache} from './ReactFiberCacheComponent.old'; import { enableClientRenderFallbackOnHydrationMismatch, enableSuspenseAvoidThisFallback, @@ -865,8 +865,8 @@ function completeWork( popRootCachePool(fiberRoot, renderLanes); let previousCache: Cache | null = null; - if (workInProgress.alternate !== null) { - previousCache = workInProgress.alternate.memoizedState.cache; + if (current !== null) { + previousCache = current.memoizedState.cache; } const cache: Cache = workInProgress.memoizedState.cache; if (cache !== previousCache) { @@ -1533,11 +1533,11 @@ function completeWork( if (enableCache) { let previousCache: Cache | null = null; if ( - workInProgress.alternate !== null && - workInProgress.alternate.memoizedState !== null && - workInProgress.alternate.memoizedState.cachePool !== null + current !== null && + current.memoizedState !== null && + current.memoizedState.cachePool !== null ) { - previousCache = workInProgress.alternate.memoizedState.cachePool.pool; + previousCache = current.memoizedState.cachePool.pool; } let cache: Cache | null = null; if ( @@ -1550,8 +1550,7 @@ function completeWork( // Run passive effects to retain/release the cache. workInProgress.flags |= Passive; } - const spawnedCachePool: SpawnedCachePool | null = (workInProgress.updateQueue: any); - if (spawnedCachePool !== null) { + if (current !== null) { popCachePool(workInProgress); } } @@ -1561,8 +1560,8 @@ function completeWork( case CacheComponent: { if (enableCache) { let previousCache: Cache | null = null; - if (workInProgress.alternate !== null) { - previousCache = workInProgress.alternate.memoizedState.cache; + if (current !== null) { + previousCache = current.memoizedState.cache; } const cache: Cache = workInProgress.memoizedState.cache; if (cache !== previousCache) { diff --git a/packages/react-reconciler/src/ReactFiberUnwindWork.new.js b/packages/react-reconciler/src/ReactFiberUnwindWork.new.js index a43c021d987e5..aa1b391b0367f 100644 --- a/packages/react-reconciler/src/ReactFiberUnwindWork.new.js +++ b/packages/react-reconciler/src/ReactFiberUnwindWork.new.js @@ -11,7 +11,7 @@ import type {ReactContext} from 'shared/ReactTypes'; import type {Fiber, FiberRoot} from './ReactInternalTypes'; import type {Lanes} from './ReactFiberLane.new'; import type {SuspenseState} from './ReactFiberSuspenseComponent.new'; -import type {Cache, SpawnedCachePool} from './ReactFiberCacheComponent.new'; +import type {Cache} from './ReactFiberCacheComponent.new'; import {resetWorkInProgressVersions as resetMutableSourceWorkInProgressVersions} from './ReactMutableSource.new'; import { @@ -52,7 +52,11 @@ import { import {transferActualDuration} from './ReactProfilerTimer.new'; import {popTreeContext} from './ReactFiberTreeContext.new'; -function unwindWork(workInProgress: Fiber, renderLanes: Lanes) { +function unwindWork( + current: Fiber | null, + workInProgress: Fiber, + renderLanes: Lanes, +) { // Note: This intentionally doesn't check if we're hydrating because comparing // to the current tree provider fiber is just as fast and less error-prone. // Ideally we would have a special version of the work loop only @@ -153,8 +157,7 @@ function unwindWork(workInProgress: Fiber, renderLanes: Lanes) { case LegacyHiddenComponent: popRenderLanes(workInProgress); if (enableCache) { - const spawnedCachePool: SpawnedCachePool | null = (workInProgress.updateQueue: any); - if (spawnedCachePool !== null) { + if (current !== null) { popCachePool(workInProgress); } } @@ -170,7 +173,11 @@ function unwindWork(workInProgress: Fiber, renderLanes: Lanes) { } } -function unwindInterruptedWork(interruptedWork: Fiber, renderLanes: Lanes) { +function unwindInterruptedWork( + current: Fiber | null, + interruptedWork: Fiber, + renderLanes: Lanes, +) { // Note: This intentionally doesn't check if we're hydrating because comparing // to the current tree provider fiber is just as fast and less error-prone. // Ideally we would have a special version of the work loop only @@ -218,8 +225,7 @@ function unwindInterruptedWork(interruptedWork: Fiber, renderLanes: Lanes) { case LegacyHiddenComponent: popRenderLanes(interruptedWork); if (enableCache) { - const spawnedCachePool: SpawnedCachePool | null = (interruptedWork.updateQueue: any); - if (spawnedCachePool !== null) { + if (current !== null) { popCachePool(interruptedWork); } } diff --git a/packages/react-reconciler/src/ReactFiberUnwindWork.old.js b/packages/react-reconciler/src/ReactFiberUnwindWork.old.js index e0cf7cc2f0fcc..cb5df61782bc3 100644 --- a/packages/react-reconciler/src/ReactFiberUnwindWork.old.js +++ b/packages/react-reconciler/src/ReactFiberUnwindWork.old.js @@ -11,7 +11,7 @@ import type {ReactContext} from 'shared/ReactTypes'; import type {Fiber, FiberRoot} from './ReactInternalTypes'; import type {Lanes} from './ReactFiberLane.old'; import type {SuspenseState} from './ReactFiberSuspenseComponent.old'; -import type {Cache, SpawnedCachePool} from './ReactFiberCacheComponent.old'; +import type {Cache} from './ReactFiberCacheComponent.old'; import {resetWorkInProgressVersions as resetMutableSourceWorkInProgressVersions} from './ReactMutableSource.old'; import { @@ -52,7 +52,11 @@ import { import {transferActualDuration} from './ReactProfilerTimer.old'; import {popTreeContext} from './ReactFiberTreeContext.old'; -function unwindWork(workInProgress: Fiber, renderLanes: Lanes) { +function unwindWork( + current: Fiber | null, + workInProgress: Fiber, + renderLanes: Lanes, +) { // Note: This intentionally doesn't check if we're hydrating because comparing // to the current tree provider fiber is just as fast and less error-prone. // Ideally we would have a special version of the work loop only @@ -153,8 +157,7 @@ function unwindWork(workInProgress: Fiber, renderLanes: Lanes) { case LegacyHiddenComponent: popRenderLanes(workInProgress); if (enableCache) { - const spawnedCachePool: SpawnedCachePool | null = (workInProgress.updateQueue: any); - if (spawnedCachePool !== null) { + if (current !== null) { popCachePool(workInProgress); } } @@ -170,7 +173,11 @@ function unwindWork(workInProgress: Fiber, renderLanes: Lanes) { } } -function unwindInterruptedWork(interruptedWork: Fiber, renderLanes: Lanes) { +function unwindInterruptedWork( + current: Fiber | null, + interruptedWork: Fiber, + renderLanes: Lanes, +) { // Note: This intentionally doesn't check if we're hydrating because comparing // to the current tree provider fiber is just as fast and less error-prone. // Ideally we would have a special version of the work loop only @@ -218,8 +225,7 @@ function unwindInterruptedWork(interruptedWork: Fiber, renderLanes: Lanes) { case LegacyHiddenComponent: popRenderLanes(interruptedWork); if (enableCache) { - const spawnedCachePool: SpawnedCachePool | null = (interruptedWork.updateQueue: any); - if (spawnedCachePool !== null) { + if (current !== null) { popCachePool(interruptedWork); } } diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 4a1880e0cf848..540d5625c891e 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -1397,7 +1397,12 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes) { if (workInProgress !== null) { let interruptedWork = workInProgress.return; while (interruptedWork !== null) { - unwindInterruptedWork(interruptedWork, workInProgressRootRenderLanes); + const current = interruptedWork.alternate; + unwindInterruptedWork( + current, + interruptedWork, + workInProgressRootRenderLanes, + ); interruptedWork = interruptedWork.return; } } @@ -1821,7 +1826,7 @@ function completeUnitOfWork(unitOfWork: Fiber): void { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, // capture values if possible. - const next = unwindWork(completedWork, subtreeRenderLanes); + const next = unwindWork(current, completedWork, subtreeRenderLanes); // Because this fiber did not complete, don't reset its lanes. @@ -2817,7 +2822,7 @@ if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // same fiber again. // Unwind the failed stack frame - unwindInterruptedWork(unitOfWork, workInProgressRootRenderLanes); + unwindInterruptedWork(current, unitOfWork, workInProgressRootRenderLanes); // Restore the original properties of the fiber. assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index b9fada5bd00b0..d24ba77bdff3f 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -1397,7 +1397,12 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes) { if (workInProgress !== null) { let interruptedWork = workInProgress.return; while (interruptedWork !== null) { - unwindInterruptedWork(interruptedWork, workInProgressRootRenderLanes); + const current = interruptedWork.alternate; + unwindInterruptedWork( + current, + interruptedWork, + workInProgressRootRenderLanes, + ); interruptedWork = interruptedWork.return; } } @@ -1821,7 +1826,7 @@ function completeUnitOfWork(unitOfWork: Fiber): void { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, // capture values if possible. - const next = unwindWork(completedWork, subtreeRenderLanes); + const next = unwindWork(current, completedWork, subtreeRenderLanes); // Because this fiber did not complete, don't reset its lanes. @@ -2817,7 +2822,7 @@ if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // same fiber again. // Unwind the failed stack frame - unwindInterruptedWork(unitOfWork, workInProgressRootRenderLanes); + unwindInterruptedWork(current, unitOfWork, workInProgressRootRenderLanes); // Restore the original properties of the fiber. assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);