mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Use recursion to traverse during mutation phase
Most of the commit phase uses iterative loops to traverse the tree. Originally we thought this would be faster than using recursion, but a while back @trueadm did some performance testing and found that the loop was slower because we assign to the `return` pointer before entering a subtree (which we have to do because the `return` pointer is not always consistent; it could point to one of two fibers). The other motivation is so we can take advantage of the JS stack to track contextual information, like the nearest host parent. We already use recursion in a few places; this changes the mutation phase to use it, too.
This commit is contained in:
+10
-2
@@ -51,14 +51,22 @@ export function resetCurrentFiber() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setCurrentFiber(fiber: Fiber) {
|
export function setCurrentFiber(fiber: Fiber | null) {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
|
ReactDebugCurrentFrame.getCurrentStack =
|
||||||
|
fiber === null ? null : getCurrentFiberStackInDev;
|
||||||
current = fiber;
|
current = fiber;
|
||||||
isRendering = false;
|
isRendering = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCurrentFiber(): Fiber | null {
|
||||||
|
if (__DEV__) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
export function setIsRendering(rendering: boolean) {
|
export function setIsRendering(rendering: boolean) {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
isRendering = rendering;
|
isRendering = rendering;
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFrom
|
|||||||
import {
|
import {
|
||||||
resetCurrentFiber as resetCurrentDebugFiberInDEV,
|
resetCurrentFiber as resetCurrentDebugFiberInDEV,
|
||||||
setCurrentFiber as setCurrentDebugFiberInDEV,
|
setCurrentFiber as setCurrentDebugFiberInDEV,
|
||||||
|
getCurrentFiber as getCurrentDebugFiberInDEV,
|
||||||
} from './ReactCurrentFiber';
|
} from './ReactCurrentFiber';
|
||||||
import {resolveDefaultProps} from './ReactFiberLazyComponent.new';
|
import {resolveDefaultProps} from './ReactFiberLazyComponent.new';
|
||||||
import {
|
import {
|
||||||
@@ -1901,62 +1902,50 @@ export function isSuspenseBoundaryBeingHidden(
|
|||||||
|
|
||||||
export function commitMutationEffects(
|
export function commitMutationEffects(
|
||||||
root: FiberRoot,
|
root: FiberRoot,
|
||||||
firstChild: Fiber,
|
finishedWork: Fiber,
|
||||||
committedLanes: Lanes,
|
committedLanes: Lanes,
|
||||||
) {
|
) {
|
||||||
inProgressLanes = committedLanes;
|
inProgressLanes = committedLanes;
|
||||||
inProgressRoot = root;
|
inProgressRoot = root;
|
||||||
nextEffect = firstChild;
|
nextEffect = finishedWork;
|
||||||
|
|
||||||
commitMutationEffects_begin(root, committedLanes);
|
setCurrentDebugFiberInDEV(finishedWork);
|
||||||
|
commitMutationEffectsOnFiber(finishedWork, root, committedLanes);
|
||||||
|
setCurrentDebugFiberInDEV(finishedWork);
|
||||||
|
|
||||||
inProgressLanes = null;
|
inProgressLanes = null;
|
||||||
inProgressRoot = null;
|
inProgressRoot = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function commitMutationEffects_begin(root: FiberRoot, lanes: Lanes) {
|
function recursivelyTraverseMutationEffects(
|
||||||
while (nextEffect !== null) {
|
root: FiberRoot,
|
||||||
const fiber = nextEffect;
|
parentFiber: Fiber,
|
||||||
|
lanes: Lanes,
|
||||||
// TODO: Should wrap this in flags check, too, as optimization
|
) {
|
||||||
const deletions = fiber.deletions;
|
// Deletions effects can be scheduled on any fiber type. They need to happen
|
||||||
if (deletions !== null) {
|
// before the children effects hae fired.
|
||||||
for (let i = 0; i < deletions.length; i++) {
|
const deletions = parentFiber.deletions;
|
||||||
const childToDelete = deletions[i];
|
if (deletions !== null) {
|
||||||
try {
|
for (let i = 0; i < deletions.length; i++) {
|
||||||
commitDeletion(root, childToDelete, fiber);
|
const childToDelete = deletions[i];
|
||||||
} catch (error) {
|
try {
|
||||||
captureCommitPhaseError(childToDelete, fiber, error);
|
commitDeletion(root, childToDelete, parentFiber);
|
||||||
}
|
} catch (error) {
|
||||||
|
captureCommitPhaseError(childToDelete, parentFiber, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const child = fiber.child;
|
const prevDebugFiber = getCurrentDebugFiberInDEV();
|
||||||
if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) {
|
if (parentFiber.subtreeFlags & MutationMask) {
|
||||||
child.return = fiber;
|
let child = parentFiber.child;
|
||||||
nextEffect = child;
|
while (child !== null) {
|
||||||
} else {
|
setCurrentDebugFiberInDEV(child);
|
||||||
commitMutationEffects_complete(root, lanes);
|
commitMutationEffectsOnFiber(child, root, lanes);
|
||||||
|
child = child.sibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
setCurrentDebugFiberInDEV(prevDebugFiber);
|
||||||
|
|
||||||
function commitMutationEffects_complete(root: FiberRoot, lanes: Lanes) {
|
|
||||||
while (nextEffect !== null) {
|
|
||||||
const fiber = nextEffect;
|
|
||||||
setCurrentDebugFiberInDEV(fiber);
|
|
||||||
commitMutationEffectsOnFiber(fiber, root, lanes);
|
|
||||||
resetCurrentDebugFiberInDEV();
|
|
||||||
|
|
||||||
const sibling = fiber.sibling;
|
|
||||||
if (sibling !== null) {
|
|
||||||
sibling.return = fiber.return;
|
|
||||||
nextEffect = sibling;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nextEffect = fiber.return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function commitMutationEffectsOnFiber(
|
function commitMutationEffectsOnFiber(
|
||||||
@@ -1975,6 +1964,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
case ForwardRef:
|
case ForwardRef:
|
||||||
case MemoComponent:
|
case MemoComponent:
|
||||||
case SimpleMemoComponent: {
|
case SimpleMemoComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2027,6 +2017,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ClassComponent: {
|
case ClassComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Ref) {
|
if (flags & Ref) {
|
||||||
@@ -2037,6 +2028,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case HostComponent: {
|
case HostComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Ref) {
|
if (flags & Ref) {
|
||||||
@@ -2045,7 +2037,13 @@ function commitMutationEffectsOnFiber(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (supportsMutation) {
|
if (supportsMutation) {
|
||||||
if (flags & ContentReset) {
|
// TODO: ContentReset gets cleared by the children during the commit
|
||||||
|
// phase. This is a refactor hazard because it means we must read
|
||||||
|
// flags the flags after `commitReconciliationEffects` has already run;
|
||||||
|
// the order matters. We should refactor so that ContentReset does not
|
||||||
|
// rely on mutating the flag during commit. Like by setting a flag
|
||||||
|
// during the render phase instead.
|
||||||
|
if (finishedWork.flags & ContentReset) {
|
||||||
const instance: Instance = finishedWork.stateNode;
|
const instance: Instance = finishedWork.stateNode;
|
||||||
try {
|
try {
|
||||||
resetTextContent(instance);
|
resetTextContent(instance);
|
||||||
@@ -2092,6 +2090,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case HostText: {
|
case HostText: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2121,6 +2120,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case HostRoot: {
|
case HostRoot: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2153,6 +2153,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case HostPortal: {
|
case HostPortal: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2170,6 +2171,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case SuspenseComponent: {
|
case SuspenseComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Visibility) {
|
if (flags & Visibility) {
|
||||||
@@ -2194,6 +2196,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case OffscreenComponent: {
|
case OffscreenComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Visibility) {
|
if (flags & Visibility) {
|
||||||
@@ -2231,6 +2234,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case SuspenseListComponent: {
|
case SuspenseListComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2240,6 +2244,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
}
|
}
|
||||||
case ScopeComponent: {
|
case ScopeComponent: {
|
||||||
if (enableScopeAPI) {
|
if (enableScopeAPI) {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
// TODO: This is a temporary solution that allowed us to transition away
|
// TODO: This is a temporary solution that allowed us to transition away
|
||||||
@@ -2258,11 +2263,13 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function commitReconciliationEffects(finishedWork: Fiber) {
|
function commitReconciliationEffects(finishedWork: Fiber) {
|
||||||
// Placement effects (insertions, reorders) can be scheduled on any fiber
|
// Placement effects (insertions, reorders) can be scheduled on any fiber
|
||||||
// type. They needs to happen after the children effects have fired, but
|
// type. They needs to happen after the children effects have fired, but
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFrom
|
|||||||
import {
|
import {
|
||||||
resetCurrentFiber as resetCurrentDebugFiberInDEV,
|
resetCurrentFiber as resetCurrentDebugFiberInDEV,
|
||||||
setCurrentFiber as setCurrentDebugFiberInDEV,
|
setCurrentFiber as setCurrentDebugFiberInDEV,
|
||||||
|
getCurrentFiber as getCurrentDebugFiberInDEV,
|
||||||
} from './ReactCurrentFiber';
|
} from './ReactCurrentFiber';
|
||||||
import {resolveDefaultProps} from './ReactFiberLazyComponent.old';
|
import {resolveDefaultProps} from './ReactFiberLazyComponent.old';
|
||||||
import {
|
import {
|
||||||
@@ -1901,62 +1902,50 @@ export function isSuspenseBoundaryBeingHidden(
|
|||||||
|
|
||||||
export function commitMutationEffects(
|
export function commitMutationEffects(
|
||||||
root: FiberRoot,
|
root: FiberRoot,
|
||||||
firstChild: Fiber,
|
finishedWork: Fiber,
|
||||||
committedLanes: Lanes,
|
committedLanes: Lanes,
|
||||||
) {
|
) {
|
||||||
inProgressLanes = committedLanes;
|
inProgressLanes = committedLanes;
|
||||||
inProgressRoot = root;
|
inProgressRoot = root;
|
||||||
nextEffect = firstChild;
|
nextEffect = finishedWork;
|
||||||
|
|
||||||
commitMutationEffects_begin(root, committedLanes);
|
setCurrentDebugFiberInDEV(finishedWork);
|
||||||
|
commitMutationEffectsOnFiber(finishedWork, root, committedLanes);
|
||||||
|
setCurrentDebugFiberInDEV(finishedWork);
|
||||||
|
|
||||||
inProgressLanes = null;
|
inProgressLanes = null;
|
||||||
inProgressRoot = null;
|
inProgressRoot = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function commitMutationEffects_begin(root: FiberRoot, lanes: Lanes) {
|
function recursivelyTraverseMutationEffects(
|
||||||
while (nextEffect !== null) {
|
root: FiberRoot,
|
||||||
const fiber = nextEffect;
|
parentFiber: Fiber,
|
||||||
|
lanes: Lanes,
|
||||||
// TODO: Should wrap this in flags check, too, as optimization
|
) {
|
||||||
const deletions = fiber.deletions;
|
// Deletions effects can be scheduled on any fiber type. They need to happen
|
||||||
if (deletions !== null) {
|
// before the children effects hae fired.
|
||||||
for (let i = 0; i < deletions.length; i++) {
|
const deletions = parentFiber.deletions;
|
||||||
const childToDelete = deletions[i];
|
if (deletions !== null) {
|
||||||
try {
|
for (let i = 0; i < deletions.length; i++) {
|
||||||
commitDeletion(root, childToDelete, fiber);
|
const childToDelete = deletions[i];
|
||||||
} catch (error) {
|
try {
|
||||||
captureCommitPhaseError(childToDelete, fiber, error);
|
commitDeletion(root, childToDelete, parentFiber);
|
||||||
}
|
} catch (error) {
|
||||||
|
captureCommitPhaseError(childToDelete, parentFiber, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const child = fiber.child;
|
const prevDebugFiber = getCurrentDebugFiberInDEV();
|
||||||
if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) {
|
if (parentFiber.subtreeFlags & MutationMask) {
|
||||||
child.return = fiber;
|
let child = parentFiber.child;
|
||||||
nextEffect = child;
|
while (child !== null) {
|
||||||
} else {
|
setCurrentDebugFiberInDEV(child);
|
||||||
commitMutationEffects_complete(root, lanes);
|
commitMutationEffectsOnFiber(child, root, lanes);
|
||||||
|
child = child.sibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
setCurrentDebugFiberInDEV(prevDebugFiber);
|
||||||
|
|
||||||
function commitMutationEffects_complete(root: FiberRoot, lanes: Lanes) {
|
|
||||||
while (nextEffect !== null) {
|
|
||||||
const fiber = nextEffect;
|
|
||||||
setCurrentDebugFiberInDEV(fiber);
|
|
||||||
commitMutationEffectsOnFiber(fiber, root, lanes);
|
|
||||||
resetCurrentDebugFiberInDEV();
|
|
||||||
|
|
||||||
const sibling = fiber.sibling;
|
|
||||||
if (sibling !== null) {
|
|
||||||
sibling.return = fiber.return;
|
|
||||||
nextEffect = sibling;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nextEffect = fiber.return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function commitMutationEffectsOnFiber(
|
function commitMutationEffectsOnFiber(
|
||||||
@@ -1975,6 +1964,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
case ForwardRef:
|
case ForwardRef:
|
||||||
case MemoComponent:
|
case MemoComponent:
|
||||||
case SimpleMemoComponent: {
|
case SimpleMemoComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2027,6 +2017,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ClassComponent: {
|
case ClassComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Ref) {
|
if (flags & Ref) {
|
||||||
@@ -2037,6 +2028,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case HostComponent: {
|
case HostComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Ref) {
|
if (flags & Ref) {
|
||||||
@@ -2045,7 +2037,13 @@ function commitMutationEffectsOnFiber(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (supportsMutation) {
|
if (supportsMutation) {
|
||||||
if (flags & ContentReset) {
|
// TODO: ContentReset gets cleared by the children during the commit
|
||||||
|
// phase. This is a refactor hazard because it means we must read
|
||||||
|
// flags the flags after `commitReconciliationEffects` has already run;
|
||||||
|
// the order matters. We should refactor so that ContentReset does not
|
||||||
|
// rely on mutating the flag during commit. Like by setting a flag
|
||||||
|
// during the render phase instead.
|
||||||
|
if (finishedWork.flags & ContentReset) {
|
||||||
const instance: Instance = finishedWork.stateNode;
|
const instance: Instance = finishedWork.stateNode;
|
||||||
try {
|
try {
|
||||||
resetTextContent(instance);
|
resetTextContent(instance);
|
||||||
@@ -2092,6 +2090,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case HostText: {
|
case HostText: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2121,6 +2120,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case HostRoot: {
|
case HostRoot: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2153,6 +2153,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case HostPortal: {
|
case HostPortal: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2170,6 +2171,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case SuspenseComponent: {
|
case SuspenseComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Visibility) {
|
if (flags & Visibility) {
|
||||||
@@ -2194,6 +2196,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case OffscreenComponent: {
|
case OffscreenComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Visibility) {
|
if (flags & Visibility) {
|
||||||
@@ -2231,6 +2234,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case SuspenseListComponent: {
|
case SuspenseListComponent: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
if (flags & Update) {
|
if (flags & Update) {
|
||||||
@@ -2240,6 +2244,7 @@ function commitMutationEffectsOnFiber(
|
|||||||
}
|
}
|
||||||
case ScopeComponent: {
|
case ScopeComponent: {
|
||||||
if (enableScopeAPI) {
|
if (enableScopeAPI) {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
// TODO: This is a temporary solution that allowed us to transition away
|
// TODO: This is a temporary solution that allowed us to transition away
|
||||||
@@ -2258,11 +2263,13 @@ function commitMutationEffectsOnFiber(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
recursivelyTraverseMutationEffects(root, finishedWork, lanes);
|
||||||
commitReconciliationEffects(finishedWork);
|
commitReconciliationEffects(finishedWork);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function commitReconciliationEffects(finishedWork: Fiber) {
|
function commitReconciliationEffects(finishedWork: Fiber) {
|
||||||
// Placement effects (insertions, reorders) can be scheduled on any fiber
|
// Placement effects (insertions, reorders) can be scheduled on any fiber
|
||||||
// type. They needs to happen after the children effects have fired, but
|
// type. They needs to happen after the children effects have fired, but
|
||||||
|
|||||||
Reference in New Issue
Block a user