Skip to content

Commit b9c6a2b

Browse files
author
Brian Vaughn
authored
Remove LayoutStatic check from commit phase (#21249)
1 parent 8f202a7 commit b9c6a2b

File tree

3 files changed

+166
-154
lines changed

3 files changed

+166
-154
lines changed

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

Lines changed: 82 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ import {
8181
MutationMask,
8282
LayoutMask,
8383
PassiveMask,
84-
LayoutStatic,
85-
RefStatic,
8684
} from './ReactFiberFlags';
8785
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
8886
import invariant from 'shared/invariant';
@@ -1027,14 +1025,18 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) {
10271025
const current = finishedWork.alternate;
10281026
const wasHidden = current !== null && current.memoizedState !== null;
10291027

1028+
// Only hide the top-most host nodes.
1029+
let hiddenHostSubtreeRoot = null;
1030+
10301031
if (supportsMutation) {
10311032
// We only have the top Fiber that was inserted but we need to recurse down its
10321033
// children to find all the terminal nodes.
10331034
let node: Fiber = finishedWork;
10341035
while (true) {
10351036
if (node.tag === HostComponent) {
10361037
const instance = node.stateNode;
1037-
if (isHidden) {
1038+
if (isHidden && hiddenHostSubtreeRoot === null) {
1039+
hiddenHostSubtreeRoot = node;
10381040
hideInstance(instance);
10391041
} else {
10401042
unhideInstance(node.stateNode, node.memoizedProps);
@@ -1043,24 +1045,21 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) {
10431045
if (enableSuspenseLayoutEffectSemantics && isModernRoot) {
10441046
// This method is called during mutation; it should detach refs within a hidden subtree.
10451047
// Attaching refs should be done elsewhere though (during layout).
1046-
if ((node.flags & RefStatic) !== NoFlags) {
1047-
if (isHidden) {
1048-
safelyDetachRef(node, finishedWork);
1049-
}
1048+
// TODO (Offscreen) Also check: flags & RefStatic
1049+
if (isHidden) {
1050+
safelyDetachRef(node, finishedWork);
10501051
}
10511052

1052-
if (
1053-
(node.subtreeFlags & (RefStatic | LayoutStatic)) !== NoFlags &&
1054-
node.child !== null
1055-
) {
1053+
// TODO (Offscreen) Also check: subtreeFlags & (RefStatic | LayoutStatic)
1054+
if (node.child !== null) {
10561055
node.child.return = node;
10571056
node = node.child;
10581057
continue;
10591058
}
10601059
}
10611060
} else if (node.tag === HostText) {
10621061
const instance = node.stateNode;
1063-
if (isHidden) {
1062+
if (isHidden && hiddenHostSubtreeRoot === null) {
10641063
hideTextInstance(instance);
10651064
} else {
10661065
unhideTextInstance(instance, node.memoizedProps);
@@ -1075,43 +1074,42 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) {
10751074
// Don't search any deeper. This tree should remain hidden.
10761075
} else if (enableSuspenseLayoutEffectSemantics && isModernRoot) {
10771076
// When a mounted Suspense subtree gets hidden again, destroy any nested layout effects.
1078-
if ((node.flags & (RefStatic | LayoutStatic)) !== NoFlags) {
1079-
switch (node.tag) {
1080-
case FunctionComponent:
1081-
case ForwardRef:
1082-
case MemoComponent:
1083-
case SimpleMemoComponent: {
1084-
// Note that refs are attached by the useImperativeHandle() hook, not by commitAttachRef()
1085-
if (isHidden && !wasHidden) {
1086-
if (
1087-
enableProfilerTimer &&
1088-
enableProfilerCommitHooks &&
1089-
node.mode & ProfileMode
1090-
) {
1091-
try {
1092-
startLayoutEffectTimer();
1093-
commitHookEffectListUnmount(HookLayout, node, finishedWork);
1094-
} finally {
1095-
recordLayoutEffectDuration(node);
1096-
}
1097-
} else {
1077+
// TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
1078+
switch (node.tag) {
1079+
case FunctionComponent:
1080+
case ForwardRef:
1081+
case MemoComponent:
1082+
case SimpleMemoComponent: {
1083+
// Note that refs are attached by the useImperativeHandle() hook, not by commitAttachRef()
1084+
if (isHidden && !wasHidden) {
1085+
if (
1086+
enableProfilerTimer &&
1087+
enableProfilerCommitHooks &&
1088+
node.mode & ProfileMode
1089+
) {
1090+
try {
1091+
startLayoutEffectTimer();
10981092
commitHookEffectListUnmount(HookLayout, node, finishedWork);
1093+
} finally {
1094+
recordLayoutEffectDuration(node);
10991095
}
1096+
} else {
1097+
commitHookEffectListUnmount(HookLayout, node, finishedWork);
11001098
}
1101-
break;
11021099
}
1103-
case ClassComponent: {
1104-
if (isHidden && !wasHidden) {
1105-
if ((node.flags & RefStatic) !== NoFlags) {
1106-
safelyDetachRef(node, finishedWork);
1107-
}
1108-
const instance = node.stateNode;
1109-
if (typeof instance.componentWillUnmount === 'function') {
1110-
safelyCallComponentWillUnmount(node, finishedWork, instance);
1111-
}
1100+
break;
1101+
}
1102+
case ClassComponent: {
1103+
if (isHidden && !wasHidden) {
1104+
// TODO (Offscreen) Check: flags & RefStatic
1105+
safelyDetachRef(node, finishedWork);
1106+
1107+
const instance = node.stateNode;
1108+
if (typeof instance.componentWillUnmount === 'function') {
1109+
safelyCallComponentWillUnmount(node, finishedWork, instance);
11121110
}
1113-
break;
11141111
}
1112+
break;
11151113
}
11161114
}
11171115

@@ -1133,8 +1131,18 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) {
11331131
if (node.return === null || node.return === finishedWork) {
11341132
return;
11351133
}
1134+
1135+
if (hiddenHostSubtreeRoot === node) {
1136+
hiddenHostSubtreeRoot = null;
1137+
}
1138+
11361139
node = node.return;
11371140
}
1141+
1142+
if (hiddenHostSubtreeRoot === node) {
1143+
hiddenHostSubtreeRoot = null;
1144+
}
1145+
11381146
node.sibling.return = node.return;
11391147
node = node.sibling;
11401148
}
@@ -2378,11 +2386,9 @@ function commitLayoutEffects_begin(
23782386
if (enableSuspenseLayoutEffectSemantics && isModernRoot) {
23792387
const visibilityChanged =
23802388
!offscreenSubtreeIsHidden && offscreenSubtreeWasHidden;
2381-
if (
2382-
visibilityChanged &&
2383-
(fiber.subtreeFlags & LayoutStatic) !== NoFlags &&
2384-
firstChild !== null
2385-
) {
2389+
2390+
// TODO (Offscreen) Also check: subtreeFlags & LayoutStatic
2391+
if (visibilityChanged && firstChild !== null) {
23862392
// We've just shown or hidden a Offscreen tree that contains layout effects.
23872393
// We only enter this code path for subtrees that are updated,
23882394
// because newly mounted ones would pass the LayoutMask check above.
@@ -2417,42 +2423,42 @@ function commitLayoutMountEffects_complete(
24172423
// Inside of an Offscreen subtree that changed visibility during this commit.
24182424
// If this subtree was hidden, layout effects will have already been destroyed (during mutation phase)
24192425
// but if it was just shown, we need to (re)create the effects now.
2420-
if ((fiber.flags & LayoutStatic) !== NoFlags) {
2421-
switch (fiber.tag) {
2422-
case FunctionComponent:
2423-
case ForwardRef:
2424-
case SimpleMemoComponent: {
2425-
if (
2426-
enableProfilerTimer &&
2427-
enableProfilerCommitHooks &&
2428-
fiber.mode & ProfileMode
2429-
) {
2430-
try {
2431-
startLayoutEffectTimer();
2432-
safelyCallCommitHookLayoutEffectListMount(fiber, fiber.return);
2433-
} finally {
2434-
recordLayoutEffectDuration(fiber);
2435-
}
2436-
} else {
2426+
// TODO (Offscreen) Check: flags & LayoutStatic
2427+
switch (fiber.tag) {
2428+
case FunctionComponent:
2429+
case ForwardRef:
2430+
case SimpleMemoComponent: {
2431+
if (
2432+
enableProfilerTimer &&
2433+
enableProfilerCommitHooks &&
2434+
fiber.mode & ProfileMode
2435+
) {
2436+
try {
2437+
startLayoutEffectTimer();
24372438
safelyCallCommitHookLayoutEffectListMount(fiber, fiber.return);
2439+
} finally {
2440+
recordLayoutEffectDuration(fiber);
24382441
}
2439-
break;
2442+
} else {
2443+
safelyCallCommitHookLayoutEffectListMount(fiber, fiber.return);
24402444
}
2441-
case ClassComponent: {
2442-
const instance = fiber.stateNode;
2445+
break;
2446+
}
2447+
case ClassComponent: {
2448+
const instance = fiber.stateNode;
2449+
if (typeof instance.componentDidMount === 'function') {
24432450
safelyCallComponentDidMount(fiber, fiber.return, instance);
2444-
break;
24452451
}
2452+
break;
24462453
}
24472454
}
24482455

2449-
if ((fiber.flags & RefStatic) !== NoFlags) {
2450-
switch (fiber.tag) {
2451-
case ClassComponent:
2452-
case HostComponent:
2453-
safelyAttachRef(fiber, fiber.return);
2454-
break;
2455-
}
2456+
// TODO (Offscreen) Check flags & RefStatic
2457+
switch (fiber.tag) {
2458+
case ClassComponent:
2459+
case HostComponent:
2460+
safelyAttachRef(fiber, fiber.return);
2461+
break;
24562462
}
24572463
} else if ((fiber.flags & LayoutMask) !== NoFlags) {
24582464
const current = fiber.alternate;

0 commit comments

Comments
 (0)