Skip to content

Commit ed429fc

Browse files
committed
Extract state and context check to separate function
The only reason we pass `updateLanes` to some begin functions is to check if we can perform an early bail out. But this is also available as `current.lanes`, so we can read it from there instead. I think the only reason we didn't do it this way originally is because components that have two phases — error and Suspense boundaries — use `workInProgress.lanes` to prevent a bail out, since during the initial render there is no `current`. But we can check the `DidCapture` flag instead, which we use elsewhere to detect the second phase.
1 parent bfabd88 commit ed429fc

File tree

4 files changed

+86
-76
lines changed

4 files changed

+86
-76
lines changed

packages/react-reconciler/src/ReactFiberBeginWork.new.js

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,6 @@ function updateMemoComponent(
409409
workInProgress: Fiber,
410410
Component: any,
411411
nextProps: any,
412-
updateLanes: Lanes,
413412
renderLanes: Lanes,
414413
): null | Fiber {
415414
if (current === null) {
@@ -437,7 +436,6 @@ function updateMemoComponent(
437436
workInProgress,
438437
resolvedType,
439438
nextProps,
440-
updateLanes,
441439
renderLanes,
442440
);
443441
}
@@ -482,7 +480,7 @@ function updateMemoComponent(
482480
}
483481
}
484482
const currentChild = ((current.child: any): Fiber); // This is always exactly one child
485-
if (!includesSomeLane(updateLanes, renderLanes)) {
483+
if (!checkScheduledUpdateOrContext(current, renderLanes)) {
486484
// This will be the props with resolved defaultProps,
487485
// unlike current.memoizedProps which will be the unresolved ones.
488486
const prevProps = currentChild.memoizedProps;
@@ -507,7 +505,6 @@ function updateSimpleMemoComponent(
507505
workInProgress: Fiber,
508506
Component: any,
509507
nextProps: any,
510-
updateLanes: Lanes,
511508
renderLanes: Lanes,
512509
): null | Fiber {
513510
// TODO: current can be non-null here even if the component
@@ -553,7 +550,7 @@ function updateSimpleMemoComponent(
553550
(__DEV__ ? workInProgress.type === current.type : true)
554551
) {
555552
didReceiveUpdate = false;
556-
if (!includesSomeLane(renderLanes, updateLanes)) {
553+
if (!checkScheduledUpdateOrContext(current, renderLanes)) {
557554
// The pending lanes were cleared at the beginning of beginWork. We're
558555
// about to bail out, but there might be other lanes that weren't
559556
// included in the current render. Usually, the priority level of the
@@ -740,7 +737,6 @@ const updateLegacyHiddenComponent = updateOffscreenComponent;
740737
function updateCacheComponent(
741738
current: Fiber | null,
742739
workInProgress: Fiber,
743-
updateLanes: Lanes,
744740
renderLanes: Lanes,
745741
) {
746742
if (!enableCache) {
@@ -762,7 +758,7 @@ function updateCacheComponent(
762758
pushCacheProvider(workInProgress, freshCache);
763759
} else {
764760
// Check for updates
765-
if (includesSomeLane(renderLanes, updateLanes)) {
761+
if (includesSomeLane(current.lanes, renderLanes)) {
766762
cloneUpdateQueue(current, workInProgress);
767763
processUpdateQueue(workInProgress, null, null, renderLanes);
768764
}
@@ -1306,7 +1302,6 @@ function mountLazyComponent(
13061302
_current,
13071303
workInProgress,
13081304
elementType,
1309-
updateLanes,
13101305
renderLanes,
13111306
) {
13121307
if (_current !== null) {
@@ -1396,7 +1391,6 @@ function mountLazyComponent(
13961391
workInProgress,
13971392
Component,
13981393
resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
1399-
updateLanes,
14001394
renderLanes,
14011395
);
14021396
return child;
@@ -3222,6 +3216,27 @@ function remountFiber(
32223216
}
32233217
}
32243218

3219+
function checkScheduledUpdateOrContext(
3220+
current: Fiber,
3221+
renderLanes: Lanes,
3222+
): boolean {
3223+
// Before performing an early bailout, we must check if there are pending
3224+
// updates or context.
3225+
const updateLanes = current.lanes;
3226+
if (includesSomeLane(renderLanes, updateLanes)) {
3227+
return true;
3228+
}
3229+
// No pending update, but because context is propagated lazily, we need
3230+
// to check for a context change before we bail out.
3231+
if (enableLazyContextPropagation) {
3232+
const dependencies = current.dependencies;
3233+
if (dependencies !== null && checkIfContextChanged(dependencies)) {
3234+
return true;
3235+
}
3236+
}
3237+
return false;
3238+
}
3239+
32253240
function attemptEarlyBailoutIfNoScheduledUpdate(
32263241
current: Fiber,
32273242
workInProgress: Fiber,
@@ -3436,8 +3451,6 @@ function beginWork(
34363451
workInProgress: Fiber,
34373452
renderLanes: Lanes,
34383453
): Fiber | null {
3439-
let updateLanes = workInProgress.lanes;
3440-
34413454
if (__DEV__) {
34423455
if (workInProgress._debugNeedsRemount && current !== null) {
34433456
// This will restart the begin phase with a new fiber.
@@ -3457,17 +3470,6 @@ function beginWork(
34573470
}
34583471

34593472
if (current !== null) {
3460-
// TODO: The factoring of this block is weird.
3461-
if (
3462-
enableLazyContextPropagation &&
3463-
!includesSomeLane(renderLanes, updateLanes)
3464-
) {
3465-
const dependencies = current.dependencies;
3466-
if (dependencies !== null && checkIfContextChanged(dependencies)) {
3467-
updateLanes = mergeLanes(updateLanes, renderLanes);
3468-
}
3469-
}
3470-
34713473
const oldProps = current.memoizedProps;
34723474
const newProps = workInProgress.pendingProps;
34733475

@@ -3480,14 +3482,23 @@ function beginWork(
34803482
// If props or context changed, mark the fiber as having performed work.
34813483
// This may be unset if the props are determined to be equal later (memo).
34823484
didReceiveUpdate = true;
3483-
} else if (!includesSomeLane(renderLanes, updateLanes)) {
3484-
didReceiveUpdate = false;
3485-
return attemptEarlyBailoutIfNoScheduledUpdate(
3486-
current,
3487-
workInProgress,
3488-
renderLanes,
3489-
);
34903485
} else {
3486+
// Neither props nor legacy context changes. Check if there's a pending
3487+
// update or context change.
3488+
if (
3489+
!checkScheduledUpdateOrContext(current, renderLanes) &&
3490+
// If this is the second pass of an error or suspense boundary, there
3491+
// may not be work scheduled on `current`, so we check for this flag.
3492+
(workInProgress.flags & DidCapture) === NoFlags
3493+
) {
3494+
// No pending updates or context. Bail out now.
3495+
didReceiveUpdate = false;
3496+
return attemptEarlyBailoutIfNoScheduledUpdate(
3497+
current,
3498+
workInProgress,
3499+
renderLanes,
3500+
);
3501+
}
34913502
if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
34923503
// This is a special case that only exists for legacy mode.
34933504
// See https://github.com/facebook/react/pull/19216.
@@ -3526,7 +3537,6 @@ function beginWork(
35263537
current,
35273538
workInProgress,
35283539
elementType,
3529-
updateLanes,
35303540
renderLanes,
35313541
);
35323542
}
@@ -3619,7 +3629,6 @@ function beginWork(
36193629
workInProgress,
36203630
type,
36213631
resolvedProps,
3622-
updateLanes,
36233632
renderLanes,
36243633
);
36253634
}
@@ -3629,7 +3638,6 @@ function beginWork(
36293638
workInProgress,
36303639
workInProgress.type,
36313640
workInProgress.pendingProps,
3632-
updateLanes,
36333641
renderLanes,
36343642
);
36353643
}
@@ -3665,12 +3673,7 @@ function beginWork(
36653673
}
36663674
case CacheComponent: {
36673675
if (enableCache) {
3668-
return updateCacheComponent(
3669-
current,
3670-
workInProgress,
3671-
updateLanes,
3672-
renderLanes,
3673-
);
3676+
return updateCacheComponent(current, workInProgress, renderLanes);
36743677
}
36753678
break;
36763679
}

packages/react-reconciler/src/ReactFiberBeginWork.old.js

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,6 @@ function updateMemoComponent(
409409
workInProgress: Fiber,
410410
Component: any,
411411
nextProps: any,
412-
updateLanes: Lanes,
413412
renderLanes: Lanes,
414413
): null | Fiber {
415414
if (current === null) {
@@ -437,7 +436,6 @@ function updateMemoComponent(
437436
workInProgress,
438437
resolvedType,
439438
nextProps,
440-
updateLanes,
441439
renderLanes,
442440
);
443441
}
@@ -482,7 +480,7 @@ function updateMemoComponent(
482480
}
483481
}
484482
const currentChild = ((current.child: any): Fiber); // This is always exactly one child
485-
if (!includesSomeLane(updateLanes, renderLanes)) {
483+
if (!checkScheduledUpdateOrContext(current, renderLanes)) {
486484
// This will be the props with resolved defaultProps,
487485
// unlike current.memoizedProps which will be the unresolved ones.
488486
const prevProps = currentChild.memoizedProps;
@@ -507,7 +505,6 @@ function updateSimpleMemoComponent(
507505
workInProgress: Fiber,
508506
Component: any,
509507
nextProps: any,
510-
updateLanes: Lanes,
511508
renderLanes: Lanes,
512509
): null | Fiber {
513510
// TODO: current can be non-null here even if the component
@@ -553,7 +550,7 @@ function updateSimpleMemoComponent(
553550
(__DEV__ ? workInProgress.type === current.type : true)
554551
) {
555552
didReceiveUpdate = false;
556-
if (!includesSomeLane(renderLanes, updateLanes)) {
553+
if (!checkScheduledUpdateOrContext(current, renderLanes)) {
557554
// The pending lanes were cleared at the beginning of beginWork. We're
558555
// about to bail out, but there might be other lanes that weren't
559556
// included in the current render. Usually, the priority level of the
@@ -740,7 +737,6 @@ const updateLegacyHiddenComponent = updateOffscreenComponent;
740737
function updateCacheComponent(
741738
current: Fiber | null,
742739
workInProgress: Fiber,
743-
updateLanes: Lanes,
744740
renderLanes: Lanes,
745741
) {
746742
if (!enableCache) {
@@ -762,7 +758,7 @@ function updateCacheComponent(
762758
pushCacheProvider(workInProgress, freshCache);
763759
} else {
764760
// Check for updates
765-
if (includesSomeLane(renderLanes, updateLanes)) {
761+
if (includesSomeLane(current.lanes, renderLanes)) {
766762
cloneUpdateQueue(current, workInProgress);
767763
processUpdateQueue(workInProgress, null, null, renderLanes);
768764
}
@@ -1306,7 +1302,6 @@ function mountLazyComponent(
13061302
_current,
13071303
workInProgress,
13081304
elementType,
1309-
updateLanes,
13101305
renderLanes,
13111306
) {
13121307
if (_current !== null) {
@@ -1396,7 +1391,6 @@ function mountLazyComponent(
13961391
workInProgress,
13971392
Component,
13981393
resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
1399-
updateLanes,
14001394
renderLanes,
14011395
);
14021396
return child;
@@ -3222,6 +3216,27 @@ function remountFiber(
32223216
}
32233217
}
32243218

3219+
function checkScheduledUpdateOrContext(
3220+
current: Fiber,
3221+
renderLanes: Lanes,
3222+
): boolean {
3223+
// Before performing an early bailout, we must check if there are pending
3224+
// updates or context.
3225+
const updateLanes = current.lanes;
3226+
if (includesSomeLane(renderLanes, updateLanes)) {
3227+
return true;
3228+
}
3229+
// No pending update, but because context is propagated lazily, we need
3230+
// to check for a context change before we bail out.
3231+
if (enableLazyContextPropagation) {
3232+
const dependencies = current.dependencies;
3233+
if (dependencies !== null && checkIfContextChanged(dependencies)) {
3234+
return true;
3235+
}
3236+
}
3237+
return false;
3238+
}
3239+
32253240
function attemptEarlyBailoutIfNoScheduledUpdate(
32263241
current: Fiber,
32273242
workInProgress: Fiber,
@@ -3436,8 +3451,6 @@ function beginWork(
34363451
workInProgress: Fiber,
34373452
renderLanes: Lanes,
34383453
): Fiber | null {
3439-
let updateLanes = workInProgress.lanes;
3440-
34413454
if (__DEV__) {
34423455
if (workInProgress._debugNeedsRemount && current !== null) {
34433456
// This will restart the begin phase with a new fiber.
@@ -3457,17 +3470,6 @@ function beginWork(
34573470
}
34583471

34593472
if (current !== null) {
3460-
// TODO: The factoring of this block is weird.
3461-
if (
3462-
enableLazyContextPropagation &&
3463-
!includesSomeLane(renderLanes, updateLanes)
3464-
) {
3465-
const dependencies = current.dependencies;
3466-
if (dependencies !== null && checkIfContextChanged(dependencies)) {
3467-
updateLanes = mergeLanes(updateLanes, renderLanes);
3468-
}
3469-
}
3470-
34713473
const oldProps = current.memoizedProps;
34723474
const newProps = workInProgress.pendingProps;
34733475

@@ -3480,14 +3482,23 @@ function beginWork(
34803482
// If props or context changed, mark the fiber as having performed work.
34813483
// This may be unset if the props are determined to be equal later (memo).
34823484
didReceiveUpdate = true;
3483-
} else if (!includesSomeLane(renderLanes, updateLanes)) {
3484-
didReceiveUpdate = false;
3485-
return attemptEarlyBailoutIfNoScheduledUpdate(
3486-
current,
3487-
workInProgress,
3488-
renderLanes,
3489-
);
34903485
} else {
3486+
// Neither props nor legacy context changes. Check if there's a pending
3487+
// update or context change.
3488+
if (
3489+
!checkScheduledUpdateOrContext(current, renderLanes) &&
3490+
// If this is the second pass of an error or suspense boundary, there
3491+
// may not be work scheduled on `current`, so we check for this flag.
3492+
(workInProgress.flags & DidCapture) === NoFlags
3493+
) {
3494+
// No pending updates or context. Bail out now.
3495+
didReceiveUpdate = false;
3496+
return attemptEarlyBailoutIfNoScheduledUpdate(
3497+
current,
3498+
workInProgress,
3499+
renderLanes,
3500+
);
3501+
}
34913502
if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
34923503
// This is a special case that only exists for legacy mode.
34933504
// See https://github.com/facebook/react/pull/19216.
@@ -3526,7 +3537,6 @@ function beginWork(
35263537
current,
35273538
workInProgress,
35283539
elementType,
3529-
updateLanes,
35303540
renderLanes,
35313541
);
35323542
}
@@ -3619,7 +3629,6 @@ function beginWork(
36193629
workInProgress,
36203630
type,
36213631
resolvedProps,
3622-
updateLanes,
36233632
renderLanes,
36243633
);
36253634
}
@@ -3629,7 +3638,6 @@ function beginWork(
36293638
workInProgress,
36303639
workInProgress.type,
36313640
workInProgress.pendingProps,
3632-
updateLanes,
36333641
renderLanes,
36343642
);
36353643
}
@@ -3665,12 +3673,7 @@ function beginWork(
36653673
}
36663674
case CacheComponent: {
36673675
if (enableCache) {
3668-
return updateCacheComponent(
3669-
current,
3670-
workInProgress,
3671-
updateLanes,
3672-
renderLanes,
3673-
);
3676+
return updateCacheComponent(current, workInProgress, renderLanes);
36743677
}
36753678
break;
36763679
}

0 commit comments

Comments
 (0)