Refactored recursive strict effects method to be iterative (#20642)
Brian Vaughn committed
Jan 22, 2021 at 11:27 UTC
a6b5256a29b60620bdeb9266d4935cb59cc1258e
2 files changed
+40
-22
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+19
-11
@@ -2551,7 +2551,6 @@ function commitDoubleInvokeEffectsInDEV(
2551
}
2552
}
2553
2554
-// TODO (strict effects) Rewrite to be iterative
2554
function invokeEffectsInDev(
2555
firstChild: Fiber,
2556
fiberFlags: Flags,
@@ -2560,19 +2559,28 @@ function invokeEffectsInDev(
2559
if (__DEV__ && enableDoubleInvokingEffects) {
2560
// We don't need to re-check for legacy roots here.
2561
// This function will not be called within legacy roots.
2563
- let fiber = firstChild;
2564
- while (fiber !== null) {
2565
- if (fiber.child !== null) {
2566
- const primarySubtreeFlag = fiber.subtreeFlags & fiberFlags;
2567
- if (primarySubtreeFlag !== NoFlags) {
2568
- invokeEffectsInDev(fiber.child, fiberFlags, invokeEffectFn);
2562
+
2563
+ let current = firstChild;
2564
+ let subtreeRoot = null;
2565
+ while (current !== null) {
2566
+ const primarySubtreeFlag = current.subtreeFlags & fiberFlags;
2567
+ if (
2568
+ current !== subtreeRoot &&
2569
+ current.child !== null &&
2570
+ primarySubtreeFlag !== NoFlags
2571
+ ) {
2572
+ current = current.child;
2573
+ } else {
2574
+ if ((current.flags & fiberFlags) !== NoFlags) {
2575
+ invokeEffectFn(current);
2576
}
2570
- }
2577
2572
- if ((fiber.flags & fiberFlags) !== NoFlags) {
2573
- invokeEffectFn(fiber);
2578
+ if (current.sibling !== null) {
2579
+ current = current.sibling;
2580
+ } else {
2581
+ current = subtreeRoot = current.return;
2582
+ }
2583
}
2575
- fiber = fiber.sibling;
2584
}
2585
}
2586
}
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+21
-11
@@ -2708,26 +2708,36 @@ function commitDoubleInvokeEffectsInDEV(
2708
}
2709
}
2710
2711
-// TODO (strict effects) Rewrite to be iterative
2711
function invokeEffectsInDev(
2712
firstChild: Fiber,
2713
fiberFlags: Flags,
2714
invokeEffectFn: (fiber: Fiber) => void,
2715
): void {
2716
if (__DEV__ && enableDoubleInvokingEffects) {
2718
- let fiber = firstChild;
2719
- while (fiber !== null) {
2720
- if (fiber.child !== null) {
2721
- const primarySubtreeFlag = fiber.subtreeFlags & fiberFlags;
2722
- if (primarySubtreeFlag !== NoFlags) {
2723
- invokeEffectsInDev(fiber.child, fiberFlags, invokeEffectFn);
2717
+ // We don't need to re-check for legacy roots here.
2718
+ // This function will not be called within legacy roots.
2719
+
2720
+ let current = firstChild;
2721
+ let subtreeRoot = null;
2722
+ while (current !== null) {
2723
+ const primarySubtreeFlag = current.subtreeFlags & fiberFlags;
2724
+ if (
2725
+ current !== subtreeRoot &&
2726
+ current.child !== null &&
2727
+ primarySubtreeFlag !== NoFlags
2728
+ ) {
2729
+ current = current.child;
2730
+ } else {
2731
+ if ((current.flags & fiberFlags) !== NoFlags) {
2732
+ invokeEffectFn(current);
2733
}
2725
- }
2734
2727
- if ((fiber.flags & fiberFlags) !== NoFlags) {
2728
- invokeEffectFn(fiber);
2735
+ if (current.sibling !== null) {
2736
+ current = current.sibling;
2737
+ } else {
2738
+ current = subtreeRoot = current.return;
2739
+ }
2740
}
2730
- fiber = fiber.sibling;
2741
}
2742
}
2743
}