From a6b5256a29b60620bdeb9266d4935cb59cc1258e Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Fri, 22 Jan 2021 11:27:39 -0800 Subject: [PATCH] Refactored recursive strict effects method to be iterative (#20642) --- .../src/ReactFiberWorkLoop.new.js | 30 ++++++++++------- .../src/ReactFiberWorkLoop.old.js | 32 ++++++++++++------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 4ceb164d94ba0..dff64f9cae95d 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -2551,7 +2551,6 @@ function commitDoubleInvokeEffectsInDEV( } } -// TODO (strict effects) Rewrite to be iterative function invokeEffectsInDev( firstChild: Fiber, fiberFlags: Flags, @@ -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; } } } diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index f292c7b36c1a6..79386f5fff5c1 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -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; } } }