Skip to content

Commit

Permalink
Refactored recursive strict effects method to be iterative (#20642)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn authored Jan 22, 2021
1 parent 3957853 commit a6b5256
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 22 deletions.
30 changes: 19 additions & 11 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -2551,7 +2551,6 @@ function commitDoubleInvokeEffectsInDEV(
}
}

// TODO (strict effects) Rewrite to be iterative
function invokeEffectsInDev(
firstChild: Fiber,
fiberFlags: Flags,
Expand All @@ -2560,19 +2559,28 @@ function invokeEffectsInDev(
if (__DEV__ && enableDoubleInvokingEffects) {
// We don't need to re-check for legacy roots here.
// This function will not be called within legacy roots.
let fiber = firstChild;
while (fiber !== null) {
if (fiber.child !== null) {
const primarySubtreeFlag = fiber.subtreeFlags & fiberFlags;
if (primarySubtreeFlag !== NoFlags) {
invokeEffectsInDev(fiber.child, fiberFlags, invokeEffectFn);

let current = firstChild;
let subtreeRoot = null;
while (current !== null) {
const primarySubtreeFlag = current.subtreeFlags & fiberFlags;
if (
current !== subtreeRoot &&
current.child !== null &&
primarySubtreeFlag !== NoFlags
) {
current = current.child;
} else {
if ((current.flags & fiberFlags) !== NoFlags) {
invokeEffectFn(current);
}
}

if ((fiber.flags & fiberFlags) !== NoFlags) {
invokeEffectFn(fiber);
if (current.sibling !== null) {
current = current.sibling;
} else {
current = subtreeRoot = current.return;
}
}
fiber = fiber.sibling;
}
}
}
Expand Down
32 changes: 21 additions & 11 deletions packages/react-reconciler/src/ReactFiberWorkLoop.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -2708,26 +2708,36 @@ function commitDoubleInvokeEffectsInDEV(
}
}

// TODO (strict effects) Rewrite to be iterative
function invokeEffectsInDev(
firstChild: Fiber,
fiberFlags: Flags,
invokeEffectFn: (fiber: Fiber) => void,
): void {
if (__DEV__ && enableDoubleInvokingEffects) {
let fiber = firstChild;
while (fiber !== null) {
if (fiber.child !== null) {
const primarySubtreeFlag = fiber.subtreeFlags & fiberFlags;
if (primarySubtreeFlag !== NoFlags) {
invokeEffectsInDev(fiber.child, fiberFlags, invokeEffectFn);
// We don't need to re-check for legacy roots here.
// This function will not be called within legacy roots.

let current = firstChild;
let subtreeRoot = null;
while (current !== null) {
const primarySubtreeFlag = current.subtreeFlags & fiberFlags;
if (
current !== subtreeRoot &&
current.child !== null &&
primarySubtreeFlag !== NoFlags
) {
current = current.child;
} else {
if ((current.flags & fiberFlags) !== NoFlags) {
invokeEffectFn(current);
}
}

if ((fiber.flags & fiberFlags) !== NoFlags) {
invokeEffectFn(fiber);
if (current.sibling !== null) {
current = current.sibling;
} else {
current = subtreeRoot = current.return;
}
}
fiber = fiber.sibling;
}
}
}
Expand Down

0 comments on commit a6b5256

Please sign in to comment.