Skip to content

Commit 157aa81

Browse files
author
Brian Vaughn
committed
Add persistent, Static subtreeTag
This allows certain concepts to persist without recalculting them, e.g. whether a subtree contains passive effects or portals. This helps for cases like nested unmounts that contain deep passive effects.
1 parent e64c6a4 commit 157aa81

File tree

3 files changed

+10
-15
lines changed

3 files changed

+10
-15
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ import {
3030
enableBlocksAPI,
3131
} from 'shared/ReactFeatureFlags';
3232
import {NoEffect, Placement} from './ReactSideEffectTags';
33-
import {NoEffect as NoSubtreeEffect} from './ReactSubtreeTags';
33+
import {
34+
NoEffect as NoSubtreeEffect,
35+
Static as StaticSubtreeEffects,
36+
} from './ReactSubtreeTags';
3437
import {ConcurrentRoot, BlockingRoot} from './ReactRootTags';
3538
import {
3639
IndeterminateComponent,
@@ -290,7 +293,6 @@ export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber {
290293
// We already have an alternate.
291294
// Reset the effect tag.
292295
workInProgress.effectTag = NoEffect;
293-
workInProgress.subtreeTag = NoSubtreeEffect;
294296
workInProgress.deletions = null;
295297

296298
// The effect list is no longer valid.
@@ -308,6 +310,7 @@ export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber {
308310
}
309311
}
310312

313+
workInProgress.subtreeTag = current.subtreeTag & StaticSubtreeEffects;
311314
workInProgress.childLanes = current.childLanes;
312315
workInProgress.lanes = current.lanes;
313316

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

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -881,19 +881,6 @@ function commitUnmount(
881881
if ((tag & HookPassive) !== NoHookEffect) {
882882
effect.tag |= HookHasEffect;
883883

884-
// subtreeTags bubble in resetChildLanes which doens't get called for unmounted subtrees.
885-
// So in the case of unmounts, we need to bubble passive effects explicitly.
886-
let ancestor = current.return;
887-
while (ancestor !== null) {
888-
ancestor.subtreeTag |= PassiveSubtreeTag;
889-
const alternate = ancestor.alternate;
890-
if (alternate !== null) {
891-
alternate.subtreeTag |= PassiveSubtreeTag;
892-
}
893-
894-
ancestor = ancestor.return;
895-
}
896-
897884
current.effectTag |= Passive;
898885

899886
if (__DEV__) {

packages/react-reconciler/src/ReactSubtreeTags.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ export const BeforeMutation = /* */ 0b0001;
1414
export const Mutation = /* */ 0b0010;
1515
export const Layout = /* */ 0b0100;
1616
export const Passive = /* */ 0b1000;
17+
18+
// Union of tags that don't get reset on clones.
19+
// This allows certain concepts to persist without recalculting them,
20+
// e.g. whether a subtree contains passive effects or portals.
21+
export const Static = /* */ 0b1000;

0 commit comments

Comments
 (0)