mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 00:20:04 +01:00
[Fiber] Reset remaining child lanes after propagating context inside Offscreen (#34658)
Otherwise, when a context is propagated into an Activity (or Suspense) this will leave work behind on the Offscreen component itself. Which will cause an extra unnecessary render and commit pass just to figure out that we're still defering it to idle. This is because lazy context propagation, when calling to schedule some work walks back up the tree all the way to the root. This is usually fine for other nodes since they'll recompute their remaining child lanes on the way up. However, for the Offscreen component we'll have already computed it. We need to set it after propagation to ensure it gets reset.
This commit is contained in:
parent
0d8ff4d8c7
commit
d8a15c49a4
|
|
@ -649,6 +649,7 @@ function updateOffscreenComponent(
|
|||
? mergeLanes(prevState.baseLanes, renderLanes)
|
||||
: renderLanes;
|
||||
|
||||
let remainingChildLanes;
|
||||
if (current !== null) {
|
||||
// Reset to the current children
|
||||
let currentChild = (workInProgress.child = current.child);
|
||||
|
|
@ -666,13 +667,12 @@ function updateOffscreenComponent(
|
|||
currentChild = currentChild.sibling;
|
||||
}
|
||||
const lanesWeJustAttempted = nextBaseLanes;
|
||||
const remainingChildLanes = removeLanes(
|
||||
remainingChildLanes = removeLanes(
|
||||
currentChildLanes,
|
||||
lanesWeJustAttempted,
|
||||
);
|
||||
workInProgress.childLanes = remainingChildLanes;
|
||||
} else {
|
||||
workInProgress.childLanes = NoLanes;
|
||||
remainingChildLanes = NoLanes;
|
||||
workInProgress.child = null;
|
||||
}
|
||||
|
||||
|
|
@ -681,6 +681,7 @@ function updateOffscreenComponent(
|
|||
workInProgress,
|
||||
nextBaseLanes,
|
||||
renderLanes,
|
||||
remainingChildLanes,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -707,8 +708,9 @@ function updateOffscreenComponent(
|
|||
// and resume this tree later.
|
||||
|
||||
// Schedule this fiber to re-render at Offscreen priority
|
||||
workInProgress.lanes = workInProgress.childLanes =
|
||||
laneToLanes(OffscreenLane);
|
||||
|
||||
const remainingChildLanes = (workInProgress.lanes =
|
||||
laneToLanes(OffscreenLane));
|
||||
|
||||
// Include the base lanes from the last render
|
||||
const nextBaseLanes =
|
||||
|
|
@ -721,6 +723,7 @@ function updateOffscreenComponent(
|
|||
workInProgress,
|
||||
nextBaseLanes,
|
||||
renderLanes,
|
||||
remainingChildLanes,
|
||||
);
|
||||
} else {
|
||||
// This is the second render. The surrounding visible content has already
|
||||
|
|
@ -826,6 +829,7 @@ function deferHiddenOffscreenComponent(
|
|||
workInProgress: Fiber,
|
||||
nextBaseLanes: Lanes,
|
||||
renderLanes: Lanes,
|
||||
remainingChildLanes: Lanes,
|
||||
) {
|
||||
const nextState: OffscreenState = {
|
||||
baseLanes: nextBaseLanes,
|
||||
|
|
@ -856,6 +860,13 @@ function deferHiddenOffscreenComponent(
|
|||
);
|
||||
}
|
||||
|
||||
// We override the remaining child lanes to be the subset that we computed
|
||||
// on the outside. We need to do this after propagating the context
|
||||
// because propagateParentContextChangesToDeferredTree may schedule
|
||||
// work which bubbles all the way up to the root and updates our child lanes.
|
||||
// We want to dismiss that since we're not going to work on it yet.
|
||||
workInProgress.childLanes = remainingChildLanes;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user