From 1f49af93f1882ba1312271c4ee5839356d9013ef Mon Sep 17 00:00:00 2001 From: kassens Date: Thu, 20 Apr 2023 15:27:55 +0000 Subject: [PATCH] Fix: Move `destroy` field to shared instance object (#26561) This reverts commit d41e5c2c3cbea2fcfa01c6347098602975d1b9fd. DiffTrain build for [1d3ffd9d9addb4aa0988b92ee6917c07c3c261ae](https://github.com/facebook/react/commit/1d3ffd9d9addb4aa0988b92ee6917c07c3c261ae) --- compiled/facebook-www/REVISION | 2 +- compiled/facebook-www/React-dev.modern.js | 2 +- compiled/facebook-www/ReactART-dev.classic.js | 66 +++++++++++----- compiled/facebook-www/ReactART-dev.modern.js | 66 +++++++++++----- .../facebook-www/ReactART-prod.classic.js | 73 +++++++++-------- compiled/facebook-www/ReactART-prod.modern.js | 73 +++++++++-------- compiled/facebook-www/ReactDOM-dev.classic.js | 66 +++++++++++----- compiled/facebook-www/ReactDOM-dev.modern.js | 66 +++++++++++----- .../facebook-www/ReactDOM-prod.classic.js | 75 +++++++++--------- compiled/facebook-www/ReactDOM-prod.modern.js | 75 +++++++++--------- .../ReactDOM-profiling.classic.js | 78 ++++++++++--------- .../facebook-www/ReactDOM-profiling.modern.js | 78 ++++++++++--------- .../ReactDOMTesting-dev.classic.js | 66 +++++++++++----- .../ReactDOMTesting-dev.modern.js | 66 +++++++++++----- .../ReactDOMTesting-prod.classic.js | 75 +++++++++--------- .../ReactDOMTesting-prod.modern.js | 75 +++++++++--------- .../ReactTestRenderer-dev.classic.js | 66 +++++++++++----- .../ReactTestRenderer-dev.modern.js | 66 +++++++++++----- 18 files changed, 684 insertions(+), 450 deletions(-) diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index 18693601bf24e..1f6c862ab8a90 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -2f18eb0ac63fdcaed3f1d4e3c375a559a552c09a +1d3ffd9d9addb4aa0988b92ee6917c07c3c261ae diff --git a/compiled/facebook-www/React-dev.modern.js b/compiled/facebook-www/React-dev.modern.js index 5e3b1bc29c3dc..7afddc7fc8d08 100644 --- a/compiled/facebook-www/React-dev.modern.js +++ b/compiled/facebook-www/React-dev.modern.js @@ -27,7 +27,7 @@ if ( } "use strict"; -var ReactVersion = "18.3.0-www-modern-b6a03dc1"; +var ReactVersion = "18.3.0-www-modern-c1d269df"; // ATTENTION // When adding new symbols to this file, diff --git a/compiled/facebook-www/ReactART-dev.classic.js b/compiled/facebook-www/ReactART-dev.classic.js index ebd63c81e0b45..4e9397c998072 100644 --- a/compiled/facebook-www/ReactART-dev.classic.js +++ b/compiled/facebook-www/ReactART-dev.classic.js @@ -69,7 +69,7 @@ function _assertThisInitialized(self) { return self; } -var ReactVersion = "18.3.0-www-classic-ccedb28a"; +var ReactVersion = "18.3.0-www-classic-cd98b4c3"; var LegacyRoot = 0; var ConcurrentRoot = 1; @@ -7343,7 +7343,21 @@ var didWarnAboutUseWrappedInTryCatch; { didWarnAboutMismatchedHooksForComponent = new Set(); didWarnAboutUseWrappedInTryCatch = new Set(); -} // These are set right before calling the component. +} // The effect "instance" is a shared object that remains the same for the entire +// lifetime of an effect. In Rust terms, a RefCell. We use it to store the +// "destroy" function that is returned from an effect, because that is stateful. +// The field is `undefined` if the effect is unmounted, or if the effect ran +// but is not stateful. We don't explicitly track whether the effect is mounted +// or unmounted because that can be inferred by the hiddenness of the fiber in +// the tree, i.e. whether there is a hidden Offscreen fiber above it. +// +// It's unfortunate that this is stored on a separate object, because it adds +// more memory per effect instance, but it's conceptually sound. I think there's +// likely a better data structure we could use for effects; perhaps just one +// array of effect instances per fiber. But I think this is OK for now despite +// the additional memory and we can follow up with performance +// optimizations later. +// These are set right before calling the component. var renderLanes$1 = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. @@ -8652,7 +8666,7 @@ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); return nextSnapshot; @@ -8707,7 +8721,7 @@ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); // Unless we're rendering a blocking lane, schedule a consistency check. // Right before committing, we will walk the tree and check if any of the @@ -8832,11 +8846,11 @@ function rerenderState(initialState) { return rerenderReducer(basicStateReducer); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, inst, deps) { var effect = { tag: tag, create: create, - destroy: destroy, + inst: inst, deps: deps, // Circular next: null @@ -8863,6 +8877,12 @@ function pushEffect(tag, create, destroy, deps) { return effect; } +function createEffectInstance() { + return { + destroy: undefined + }; +} + var stackContainsErrorMessage = null; function getCallerStackFrame() { @@ -8963,7 +8983,7 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - undefined, + createEffectInstance(), nextDeps ); } @@ -8971,17 +8991,16 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - var destroy = undefined; // currentHook is null when rerendering after a render phase state update. + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null when rerendering after a render phase state update. if (currentHook !== null) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); return; } } @@ -8991,7 +9010,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - destroy, + inst, nextDeps ); } @@ -19298,10 +19317,12 @@ function commitHookEffectListUnmount( do { if ((effect.tag & flags) === flags) { // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { + inst.destroy = undefined; + if (enableSchedulingProfiler) { if ((flags & Passive) !== NoFlags) { markComponentPassiveEffectUnmountStarted(finishedWork); @@ -19365,7 +19386,9 @@ function commitHookEffectListMount(flags, finishedWork) { } } - effect.destroy = create(); + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; { if ((flags & Insertion) !== NoFlags) { @@ -19382,8 +19405,6 @@ function commitHookEffectListMount(flags, finishedWork) { } { - var destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { var hookName = void 0; @@ -20767,12 +20788,13 @@ function commitDeletionEffectsOnFiber( var effect = firstEffect; do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -20785,6 +20807,7 @@ function commitDeletionEffectsOnFiber( if (shouldProfile(deletedFiber)) { startLayoutEffectTimer(); + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -20792,6 +20815,7 @@ function commitDeletionEffectsOnFiber( ); recordLayoutEffectDuration(deletedFiber); } else { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, diff --git a/compiled/facebook-www/ReactART-dev.modern.js b/compiled/facebook-www/ReactART-dev.modern.js index fcd08b7a32b97..ee93532213d9c 100644 --- a/compiled/facebook-www/ReactART-dev.modern.js +++ b/compiled/facebook-www/ReactART-dev.modern.js @@ -69,7 +69,7 @@ function _assertThisInitialized(self) { return self; } -var ReactVersion = "18.3.0-www-modern-89053274"; +var ReactVersion = "18.3.0-www-modern-01966321"; var LegacyRoot = 0; var ConcurrentRoot = 1; @@ -7099,7 +7099,21 @@ var didWarnAboutUseWrappedInTryCatch; { didWarnAboutMismatchedHooksForComponent = new Set(); didWarnAboutUseWrappedInTryCatch = new Set(); -} // These are set right before calling the component. +} // The effect "instance" is a shared object that remains the same for the entire +// lifetime of an effect. In Rust terms, a RefCell. We use it to store the +// "destroy" function that is returned from an effect, because that is stateful. +// The field is `undefined` if the effect is unmounted, or if the effect ran +// but is not stateful. We don't explicitly track whether the effect is mounted +// or unmounted because that can be inferred by the hiddenness of the fiber in +// the tree, i.e. whether there is a hidden Offscreen fiber above it. +// +// It's unfortunate that this is stored on a separate object, because it adds +// more memory per effect instance, but it's conceptually sound. I think there's +// likely a better data structure we could use for effects; perhaps just one +// array of effect instances per fiber. But I think this is OK for now despite +// the additional memory and we can follow up with performance +// optimizations later. +// These are set right before calling the component. var renderLanes$1 = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. @@ -8408,7 +8422,7 @@ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); return nextSnapshot; @@ -8463,7 +8477,7 @@ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); // Unless we're rendering a blocking lane, schedule a consistency check. // Right before committing, we will walk the tree and check if any of the @@ -8588,11 +8602,11 @@ function rerenderState(initialState) { return rerenderReducer(basicStateReducer); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, inst, deps) { var effect = { tag: tag, create: create, - destroy: destroy, + inst: inst, deps: deps, // Circular next: null @@ -8619,6 +8633,12 @@ function pushEffect(tag, create, destroy, deps) { return effect; } +function createEffectInstance() { + return { + destroy: undefined + }; +} + var stackContainsErrorMessage = null; function getCallerStackFrame() { @@ -8719,7 +8739,7 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - undefined, + createEffectInstance(), nextDeps ); } @@ -8727,17 +8747,16 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - var destroy = undefined; // currentHook is null when rerendering after a render phase state update. + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null when rerendering after a render phase state update. if (currentHook !== null) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); return; } } @@ -8747,7 +8766,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - destroy, + inst, nextDeps ); } @@ -18963,10 +18982,12 @@ function commitHookEffectListUnmount( do { if ((effect.tag & flags) === flags) { // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { + inst.destroy = undefined; + if (enableSchedulingProfiler) { if ((flags & Passive) !== NoFlags) { markComponentPassiveEffectUnmountStarted(finishedWork); @@ -19030,7 +19051,9 @@ function commitHookEffectListMount(flags, finishedWork) { } } - effect.destroy = create(); + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; { if ((flags & Insertion) !== NoFlags) { @@ -19047,8 +19070,6 @@ function commitHookEffectListMount(flags, finishedWork) { } { - var destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { var hookName = void 0; @@ -20432,12 +20453,13 @@ function commitDeletionEffectsOnFiber( var effect = firstEffect; do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -20450,6 +20472,7 @@ function commitDeletionEffectsOnFiber( if (shouldProfile(deletedFiber)) { startLayoutEffectTimer(); + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -20457,6 +20480,7 @@ function commitDeletionEffectsOnFiber( ); recordLayoutEffectDuration(deletedFiber); } else { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, diff --git a/compiled/facebook-www/ReactART-prod.classic.js b/compiled/facebook-www/ReactART-prod.classic.js index e456891567993..91605ce428803 100644 --- a/compiled/facebook-www/ReactART-prod.classic.js +++ b/compiled/facebook-www/ReactART-prod.classic.js @@ -2682,7 +2682,7 @@ function updateSyncExternalStore(subscribe, getSnapshot) { pushEffect( 9, updateStoreInstance.bind(null, fiber, hook, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); subscribe = workInProgressRoot; @@ -2748,18 +2748,18 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } -function pushEffect(tag, create, destroy, deps) { - tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; +function pushEffect(tag, create, inst, deps) { + tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; null === create ? ((create = createFunctionComponentUpdateQueue()), (currentlyRenderingFiber$1.updateQueue = create), (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy + : ((inst = create.lastEffect), + null === inst ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), + : ((deps = inst.next), + (inst.next = tag), (tag.next = deps), (create.lastEffect = tag))); return tag; @@ -2773,24 +2773,20 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( 1 | hookFlags, create, - void 0, + { destroy: void 0 }, void 0 === deps ? null : deps ); } function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); deps = void 0 === deps ? null : deps; - var destroy = void 0; - if (null !== currentHook) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); - return; - } - } - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); + var inst = hook.memoizedState.inst; + null !== currentHook && + null !== deps && + areHookInputsEqual(deps, currentHook.memoizedState.deps) + ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) + : ((currentlyRenderingFiber$1.flags |= fiberFlags), + (hook.memoizedState = pushEffect(1 | hookFlags, create, inst, deps))); } function mountEffect(create, deps) { mountEffectImpl(8390656, 8, create, deps); @@ -3140,7 +3136,7 @@ var HooksDispatcherOnMount = { pushEffect( 9, updateStoreInstance.bind(null, fiber, root, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); return nextSnapshot; @@ -5964,10 +5960,11 @@ function commitHookEffectListUnmount( var effect = (updateQueue = updateQueue.next); do { if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; + var inst = effect.inst, + destroy = inst.destroy; void 0 !== destroy && - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + ((inst.destroy = void 0), + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy)); } effect = effect.next; } while (effect !== updateQueue); @@ -5980,8 +5977,10 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create = effect.create; - effect.destroy = create(); + var create = effect.create, + inst = effect.inst; + create = create(); + inst.destroy = create; } effect = effect.next; } while (effect !== finishedWork); @@ -6441,18 +6440,24 @@ function commitDeletionEffectsOnFiber( ) { prevHostParentIsContainer = prevHostParent = prevHostParent.next; do { - var _effect = prevHostParentIsContainer, - destroy = _effect.destroy; - _effect = _effect.tag; + var tag = prevHostParentIsContainer.tag, + inst = prevHostParentIsContainer.inst, + destroy = inst.destroy; void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && + (0 !== (tag & 2) + ? ((inst.destroy = void 0), safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy - )); + )) + : 0 !== (tag & 4) && + ((inst.destroy = void 0), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ))); prevHostParentIsContainer = prevHostParentIsContainer.next; } while (prevHostParentIsContainer !== prevHostParent); } @@ -10067,7 +10072,7 @@ var slice = Array.prototype.slice, return null; }, bundleType: 0, - version: "18.3.0-www-classic-3b2e6228", + version: "18.3.0-www-classic-0d8af644", rendererPackageName: "react-art" }; var internals$jscomp$inline_1344 = { @@ -10098,7 +10103,7 @@ var internals$jscomp$inline_1344 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-classic-3b2e6228" + reconcilerVersion: "18.3.0-www-classic-0d8af644" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1345 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled/facebook-www/ReactART-prod.modern.js b/compiled/facebook-www/ReactART-prod.modern.js index 97a771babad59..9822e1ed35c3a 100644 --- a/compiled/facebook-www/ReactART-prod.modern.js +++ b/compiled/facebook-www/ReactART-prod.modern.js @@ -2488,7 +2488,7 @@ function updateSyncExternalStore(subscribe, getSnapshot) { pushEffect( 9, updateStoreInstance.bind(null, fiber, hook, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); subscribe = workInProgressRoot; @@ -2554,18 +2554,18 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } -function pushEffect(tag, create, destroy, deps) { - tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; +function pushEffect(tag, create, inst, deps) { + tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; null === create ? ((create = createFunctionComponentUpdateQueue()), (currentlyRenderingFiber$1.updateQueue = create), (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy + : ((inst = create.lastEffect), + null === inst ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), + : ((deps = inst.next), + (inst.next = tag), (tag.next = deps), (create.lastEffect = tag))); return tag; @@ -2579,24 +2579,20 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( 1 | hookFlags, create, - void 0, + { destroy: void 0 }, void 0 === deps ? null : deps ); } function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); deps = void 0 === deps ? null : deps; - var destroy = void 0; - if (null !== currentHook) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); - return; - } - } - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); + var inst = hook.memoizedState.inst; + null !== currentHook && + null !== deps && + areHookInputsEqual(deps, currentHook.memoizedState.deps) + ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) + : ((currentlyRenderingFiber$1.flags |= fiberFlags), + (hook.memoizedState = pushEffect(1 | hookFlags, create, inst, deps))); } function mountEffect(create, deps) { mountEffectImpl(8390656, 8, create, deps); @@ -2946,7 +2942,7 @@ var HooksDispatcherOnMount = { pushEffect( 9, updateStoreInstance.bind(null, fiber, root, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); return nextSnapshot; @@ -5700,10 +5696,11 @@ function commitHookEffectListUnmount( var effect = (updateQueue = updateQueue.next); do { if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; + var inst = effect.inst, + destroy = inst.destroy; void 0 !== destroy && - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + ((inst.destroy = void 0), + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy)); } effect = effect.next; } while (effect !== updateQueue); @@ -5716,8 +5713,10 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create = effect.create; - effect.destroy = create(); + var create = effect.create, + inst = effect.inst; + create = create(); + inst.destroy = create; } effect = effect.next; } while (effect !== finishedWork); @@ -6177,18 +6176,24 @@ function commitDeletionEffectsOnFiber( ) { prevHostParentIsContainer = prevHostParent = prevHostParent.next; do { - var _effect = prevHostParentIsContainer, - destroy = _effect.destroy; - _effect = _effect.tag; + var tag = prevHostParentIsContainer.tag, + inst = prevHostParentIsContainer.inst, + destroy = inst.destroy; void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && + (0 !== (tag & 2) + ? ((inst.destroy = void 0), safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy - )); + )) + : 0 !== (tag & 4) && + ((inst.destroy = void 0), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ))); prevHostParentIsContainer = prevHostParentIsContainer.next; } while (prevHostParentIsContainer !== prevHostParent); } @@ -9732,7 +9737,7 @@ var slice = Array.prototype.slice, return null; }, bundleType: 0, - version: "18.3.0-www-modern-21f0ca0b", + version: "18.3.0-www-modern-01a8837f", rendererPackageName: "react-art" }; var internals$jscomp$inline_1324 = { @@ -9763,7 +9768,7 @@ var internals$jscomp$inline_1324 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-modern-21f0ca0b" + reconcilerVersion: "18.3.0-www-modern-01a8837f" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1325 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled/facebook-www/ReactDOM-dev.classic.js b/compiled/facebook-www/ReactDOM-dev.classic.js index bafb19be3c8b9..b2fa99d730dab 100644 --- a/compiled/facebook-www/ReactDOM-dev.classic.js +++ b/compiled/facebook-www/ReactDOM-dev.classic.js @@ -11866,7 +11866,21 @@ var didWarnAboutUseWrappedInTryCatch; { didWarnAboutMismatchedHooksForComponent = new Set(); didWarnAboutUseWrappedInTryCatch = new Set(); -} // These are set right before calling the component. +} // The effect "instance" is a shared object that remains the same for the entire +// lifetime of an effect. In Rust terms, a RefCell. We use it to store the +// "destroy" function that is returned from an effect, because that is stateful. +// The field is `undefined` if the effect is unmounted, or if the effect ran +// but is not stateful. We don't explicitly track whether the effect is mounted +// or unmounted because that can be inferred by the hiddenness of the fiber in +// the tree, i.e. whether there is a hidden Offscreen fiber above it. +// +// It's unfortunate that this is stored on a separate object, because it adds +// more memory per effect instance, but it's conceptually sound. I think there's +// likely a better data structure we could use for effects; perhaps just one +// array of effect instances per fiber. But I think this is OK for now despite +// the additional memory and we can follow up with performance +// optimizations later. +// These are set right before calling the component. var renderLanes$1 = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. @@ -13209,7 +13223,7 @@ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); return nextSnapshot; @@ -13264,7 +13278,7 @@ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); // Unless we're rendering a blocking lane, schedule a consistency check. // Right before committing, we will walk the tree and check if any of the @@ -13389,11 +13403,11 @@ function rerenderState(initialState) { return rerenderReducer(basicStateReducer); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, inst, deps) { var effect = { tag: tag, create: create, - destroy: destroy, + inst: inst, deps: deps, // Circular next: null @@ -13420,6 +13434,12 @@ function pushEffect(tag, create, destroy, deps) { return effect; } +function createEffectInstance() { + return { + destroy: undefined + }; +} + var stackContainsErrorMessage = null; function getCallerStackFrame() { @@ -13520,7 +13540,7 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - undefined, + createEffectInstance(), nextDeps ); } @@ -13528,17 +13548,16 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - var destroy = undefined; // currentHook is null when rerendering after a render phase state update. + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null when rerendering after a render phase state update. if (currentHook !== null) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); return; } } @@ -13548,7 +13567,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - destroy, + inst, nextDeps ); } @@ -24490,10 +24509,12 @@ function commitHookEffectListUnmount( do { if ((effect.tag & flags) === flags) { // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { + inst.destroy = undefined; + if (enableSchedulingProfiler) { if ((flags & Passive) !== NoFlags) { markComponentPassiveEffectUnmountStarted(finishedWork); @@ -24557,7 +24578,9 @@ function commitHookEffectListMount(flags, finishedWork) { } } - effect.destroy = create(); + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; { if ((flags & Insertion) !== NoFlags) { @@ -24574,8 +24597,6 @@ function commitHookEffectListMount(flags, finishedWork) { } { - var destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { var hookName = void 0; @@ -26056,12 +26077,13 @@ function commitDeletionEffectsOnFiber( var effect = firstEffect; do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -26074,6 +26096,7 @@ function commitDeletionEffectsOnFiber( if (shouldProfile(deletedFiber)) { startLayoutEffectTimer(); + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -26081,6 +26104,7 @@ function commitDeletionEffectsOnFiber( ); recordLayoutEffectDuration(deletedFiber); } else { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -33899,7 +33923,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.3.0-www-classic-bf9f5104"; +var ReactVersion = "18.3.0-www-classic-d0b2190b"; function createPortal$1( children, diff --git a/compiled/facebook-www/ReactDOM-dev.modern.js b/compiled/facebook-www/ReactDOM-dev.modern.js index 2ffafa3987ea0..3e38303112114 100644 --- a/compiled/facebook-www/ReactDOM-dev.modern.js +++ b/compiled/facebook-www/ReactDOM-dev.modern.js @@ -11801,7 +11801,21 @@ var didWarnAboutUseWrappedInTryCatch; { didWarnAboutMismatchedHooksForComponent = new Set(); didWarnAboutUseWrappedInTryCatch = new Set(); -} // These are set right before calling the component. +} // The effect "instance" is a shared object that remains the same for the entire +// lifetime of an effect. In Rust terms, a RefCell. We use it to store the +// "destroy" function that is returned from an effect, because that is stateful. +// The field is `undefined` if the effect is unmounted, or if the effect ran +// but is not stateful. We don't explicitly track whether the effect is mounted +// or unmounted because that can be inferred by the hiddenness of the fiber in +// the tree, i.e. whether there is a hidden Offscreen fiber above it. +// +// It's unfortunate that this is stored on a separate object, because it adds +// more memory per effect instance, but it's conceptually sound. I think there's +// likely a better data structure we could use for effects; perhaps just one +// array of effect instances per fiber. But I think this is OK for now despite +// the additional memory and we can follow up with performance +// optimizations later. +// These are set right before calling the component. var renderLanes$1 = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. @@ -13144,7 +13158,7 @@ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); return nextSnapshot; @@ -13199,7 +13213,7 @@ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); // Unless we're rendering a blocking lane, schedule a consistency check. // Right before committing, we will walk the tree and check if any of the @@ -13324,11 +13338,11 @@ function rerenderState(initialState) { return rerenderReducer(basicStateReducer); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, inst, deps) { var effect = { tag: tag, create: create, - destroy: destroy, + inst: inst, deps: deps, // Circular next: null @@ -13355,6 +13369,12 @@ function pushEffect(tag, create, destroy, deps) { return effect; } +function createEffectInstance() { + return { + destroy: undefined + }; +} + var stackContainsErrorMessage = null; function getCallerStackFrame() { @@ -13455,7 +13475,7 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - undefined, + createEffectInstance(), nextDeps ); } @@ -13463,17 +13483,16 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - var destroy = undefined; // currentHook is null when rerendering after a render phase state update. + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null when rerendering after a render phase state update. if (currentHook !== null) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); return; } } @@ -13483,7 +13502,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - destroy, + inst, nextDeps ); } @@ -24334,10 +24353,12 @@ function commitHookEffectListUnmount( do { if ((effect.tag & flags) === flags) { // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { + inst.destroy = undefined; + if (enableSchedulingProfiler) { if ((flags & Passive) !== NoFlags) { markComponentPassiveEffectUnmountStarted(finishedWork); @@ -24401,7 +24422,9 @@ function commitHookEffectListMount(flags, finishedWork) { } } - effect.destroy = create(); + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; { if ((flags & Insertion) !== NoFlags) { @@ -24418,8 +24441,6 @@ function commitHookEffectListMount(flags, finishedWork) { } { - var destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { var hookName = void 0; @@ -25900,12 +25921,13 @@ function commitDeletionEffectsOnFiber( var effect = firstEffect; do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -25918,6 +25940,7 @@ function commitDeletionEffectsOnFiber( if (shouldProfile(deletedFiber)) { startLayoutEffectTimer(); + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -25925,6 +25948,7 @@ function commitDeletionEffectsOnFiber( ); recordLayoutEffectDuration(deletedFiber); } else { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -33738,7 +33762,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.3.0-www-modern-21f0ca0b"; +var ReactVersion = "18.3.0-www-modern-01a8837f"; function createPortal$1( children, diff --git a/compiled/facebook-www/ReactDOM-prod.classic.js b/compiled/facebook-www/ReactDOM-prod.classic.js index 9f2bcdd725c77..e4ceebd6fc3e4 100644 --- a/compiled/facebook-www/ReactDOM-prod.classic.js +++ b/compiled/facebook-www/ReactDOM-prod.classic.js @@ -3413,7 +3413,7 @@ function updateSyncExternalStore(subscribe, getSnapshot) { pushEffect( 9, updateStoreInstance.bind(null, fiber, hook, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); subscribe = workInProgressRoot; @@ -3479,18 +3479,18 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } -function pushEffect(tag, create, destroy, deps) { - tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; +function pushEffect(tag, create, inst, deps) { + tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; null === create ? ((create = createFunctionComponentUpdateQueue()), (currentlyRenderingFiber$1.updateQueue = create), (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy + : ((inst = create.lastEffect), + null === inst ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), + : ((deps = inst.next), + (inst.next = tag), (tag.next = deps), (create.lastEffect = tag))); return tag; @@ -3504,24 +3504,20 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( 1 | hookFlags, create, - void 0, + { destroy: void 0 }, void 0 === deps ? null : deps ); } function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); deps = void 0 === deps ? null : deps; - var destroy = void 0; - if (null !== currentHook) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); - return; - } - } - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); + var inst = hook.memoizedState.inst; + null !== currentHook && + null !== deps && + areHookInputsEqual(deps, currentHook.memoizedState.deps) + ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) + : ((currentlyRenderingFiber$1.flags |= fiberFlags), + (hook.memoizedState = pushEffect(1 | hookFlags, create, inst, deps))); } function mountEffect(create, deps) { mountEffectImpl(8390656, 8, create, deps); @@ -3883,7 +3879,7 @@ var HooksDispatcherOnMount = { getServerSnapshot, getSnapshot ), - void 0, + { destroy: void 0 }, null ); return getServerSnapshot; @@ -7209,10 +7205,11 @@ function commitHookEffectListUnmount( var effect = (updateQueue = updateQueue.next); do { if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; + var inst = effect.inst, + destroy = inst.destroy; void 0 !== destroy && - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + ((inst.destroy = void 0), + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy)); } effect = effect.next; } while (effect !== updateQueue); @@ -7225,8 +7222,10 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create = effect.create; - effect.destroy = create(); + var create = effect.create, + inst = effect.inst; + create = create(); + inst.destroy = create; } effect = effect.next; } while (effect !== finishedWork); @@ -7771,18 +7770,24 @@ function commitDeletionEffectsOnFiber( ) { prevHostParentIsContainer = prevHostParent = prevHostParent.next; do { - var _effect = prevHostParentIsContainer, - destroy = _effect.destroy; - _effect = _effect.tag; + var tag = prevHostParentIsContainer.tag, + inst = prevHostParentIsContainer.inst, + destroy = inst.destroy; void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && + (0 !== (tag & 2) + ? ((inst.destroy = void 0), safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy - )); + )) + : 0 !== (tag & 4) && + ((inst.destroy = void 0), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ))); prevHostParentIsContainer = prevHostParentIsContainer.next; } while (prevHostParentIsContainer !== prevHostParent); } @@ -15970,7 +15975,7 @@ Internals.Events = [ var devToolsConfig$jscomp$inline_1812 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-classic-067cf99f", + version: "18.3.0-www-classic-0cb76979", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2208 = { @@ -16000,7 +16005,7 @@ var internals$jscomp$inline_2208 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-classic-067cf99f" + reconcilerVersion: "18.3.0-www-classic-0cb76979" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2209 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -16240,4 +16245,4 @@ exports.unstable_renderSubtreeIntoContainer = function ( ); }; exports.unstable_runWithPriority = runWithPriority; -exports.version = "18.3.0-www-classic-067cf99f"; +exports.version = "18.3.0-www-classic-0cb76979"; diff --git a/compiled/facebook-www/ReactDOM-prod.modern.js b/compiled/facebook-www/ReactDOM-prod.modern.js index b5ce18e14b288..b05ab82f74f4b 100644 --- a/compiled/facebook-www/ReactDOM-prod.modern.js +++ b/compiled/facebook-www/ReactDOM-prod.modern.js @@ -3301,7 +3301,7 @@ function updateSyncExternalStore(subscribe, getSnapshot) { pushEffect( 9, updateStoreInstance.bind(null, fiber, hook, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); subscribe = workInProgressRoot; @@ -3367,18 +3367,18 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } -function pushEffect(tag, create, destroy, deps) { - tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; +function pushEffect(tag, create, inst, deps) { + tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; null === create ? ((create = createFunctionComponentUpdateQueue()), (currentlyRenderingFiber$1.updateQueue = create), (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy + : ((inst = create.lastEffect), + null === inst ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), + : ((deps = inst.next), + (inst.next = tag), (tag.next = deps), (create.lastEffect = tag))); return tag; @@ -3392,24 +3392,20 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( 1 | hookFlags, create, - void 0, + { destroy: void 0 }, void 0 === deps ? null : deps ); } function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); deps = void 0 === deps ? null : deps; - var destroy = void 0; - if (null !== currentHook) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); - return; - } - } - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); + var inst = hook.memoizedState.inst; + null !== currentHook && + null !== deps && + areHookInputsEqual(deps, currentHook.memoizedState.deps) + ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) + : ((currentlyRenderingFiber$1.flags |= fiberFlags), + (hook.memoizedState = pushEffect(1 | hookFlags, create, inst, deps))); } function mountEffect(create, deps) { mountEffectImpl(8390656, 8, create, deps); @@ -3771,7 +3767,7 @@ var HooksDispatcherOnMount = { getServerSnapshot, getSnapshot ), - void 0, + { destroy: void 0 }, null ); return getServerSnapshot; @@ -7040,10 +7036,11 @@ function commitHookEffectListUnmount( var effect = (updateQueue = updateQueue.next); do { if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; + var inst = effect.inst, + destroy = inst.destroy; void 0 !== destroy && - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + ((inst.destroy = void 0), + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy)); } effect = effect.next; } while (effect !== updateQueue); @@ -7056,8 +7053,10 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create = effect.create; - effect.destroy = create(); + var create = effect.create, + inst = effect.inst; + create = create(); + inst.destroy = create; } effect = effect.next; } while (effect !== finishedWork); @@ -7602,18 +7601,24 @@ function commitDeletionEffectsOnFiber( ) { prevHostParentIsContainer = prevHostParent = prevHostParent.next; do { - var _effect = prevHostParentIsContainer, - destroy = _effect.destroy; - _effect = _effect.tag; + var tag = prevHostParentIsContainer.tag, + inst = prevHostParentIsContainer.inst, + destroy = inst.destroy; void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && + (0 !== (tag & 2) + ? ((inst.destroy = void 0), safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy - )); + )) + : 0 !== (tag & 4) && + ((inst.destroy = void 0), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ))); prevHostParentIsContainer = prevHostParentIsContainer.next; } while (prevHostParentIsContainer !== prevHostParent); } @@ -15497,7 +15502,7 @@ Internals.Events = [ var devToolsConfig$jscomp$inline_1770 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-modern-1e3e94dc", + version: "18.3.0-www-modern-d7a3db8a", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2171 = { @@ -15528,7 +15533,7 @@ var internals$jscomp$inline_2171 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-modern-1e3e94dc" + reconcilerVersion: "18.3.0-www-modern-d7a3db8a" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2172 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -15697,4 +15702,4 @@ exports.unstable_createEventHandle = function (type, options) { return eventHandle; }; exports.unstable_runWithPriority = runWithPriority; -exports.version = "18.3.0-www-modern-1e3e94dc"; +exports.version = "18.3.0-www-modern-d7a3db8a"; diff --git a/compiled/facebook-www/ReactDOM-profiling.classic.js b/compiled/facebook-www/ReactDOM-profiling.classic.js index e07a755de828c..04fe963f927da 100644 --- a/compiled/facebook-www/ReactDOM-profiling.classic.js +++ b/compiled/facebook-www/ReactDOM-profiling.classic.js @@ -3557,7 +3557,7 @@ function updateSyncExternalStore(subscribe, getSnapshot) { pushEffect( 9, updateStoreInstance.bind(null, fiber, hook, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); subscribe = workInProgressRoot; @@ -3623,18 +3623,18 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } -function pushEffect(tag, create, destroy, deps) { - tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; +function pushEffect(tag, create, inst, deps) { + tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; null === create ? ((create = createFunctionComponentUpdateQueue()), (currentlyRenderingFiber$1.updateQueue = create), (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy + : ((inst = create.lastEffect), + null === inst ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), + : ((deps = inst.next), + (inst.next = tag), (tag.next = deps), (create.lastEffect = tag))); return tag; @@ -3648,24 +3648,20 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( 1 | hookFlags, create, - void 0, + { destroy: void 0 }, void 0 === deps ? null : deps ); } function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); deps = void 0 === deps ? null : deps; - var destroy = void 0; - if (null !== currentHook) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); - return; - } - } - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); + var inst = hook.memoizedState.inst; + null !== currentHook && + null !== deps && + areHookInputsEqual(deps, currentHook.memoizedState.deps) + ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) + : ((currentlyRenderingFiber$1.flags |= fiberFlags), + (hook.memoizedState = pushEffect(1 | hookFlags, create, inst, deps))); } function mountEffect(create, deps) { mountEffectImpl(8390656, 8, create, deps); @@ -4029,7 +4025,7 @@ var HooksDispatcherOnMount = { getServerSnapshot, getSnapshot ), - void 0, + { destroy: void 0 }, null ); return getServerSnapshot; @@ -7557,10 +7553,11 @@ function commitHookEffectListUnmount( var effect = (updateQueue = updateQueue.next); do { if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; + var inst = effect.inst, + destroy = inst.destroy; void 0 !== destroy && - (enableSchedulingProfiler && + ((inst.destroy = void 0), + enableSchedulingProfiler && (0 !== (flags & 8) ? enableSchedulingProfiler && null !== injectedProfilingHooks && @@ -7610,8 +7607,10 @@ function commitHookEffectListMount(flags, finishedWork) { injectedProfilingHooks.markComponentLayoutEffectMountStarted( finishedWork )); - var create = effect.create; - effect.destroy = create(); + var create = effect.create, + inst = effect.inst; + create = create(); + inst.destroy = create; enableSchedulingProfiler && (0 !== (flags & 8) ? enableSchedulingProfiler && @@ -8278,28 +8277,35 @@ function commitDeletionEffectsOnFiber( ) { prevHostParentIsContainer = prevHostParent = prevHostParent.next; do { - var _effect = prevHostParentIsContainer, - destroy = _effect.destroy; - _effect = _effect.tag; + var tag = prevHostParentIsContainer.tag, + inst = prevHostParentIsContainer.inst, + destroy = inst.destroy; void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && + (0 !== (tag & 2) + ? ((inst.destroy = void 0), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + )) + : 0 !== (tag & 4) && (enableSchedulingProfiler && markComponentLayoutEffectUnmountStarted(deletedFiber), shouldProfile(deletedFiber) ? (startLayoutEffectTimer(), + (inst.destroy = void 0), safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy ), recordLayoutEffectDuration(deletedFiber)) - : safelyCallDestroy( + : ((inst.destroy = void 0), + safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy - ), + )), enableSchedulingProfiler && markComponentLayoutEffectUnmountStopped())); prevHostParentIsContainer = prevHostParentIsContainer.next; @@ -16744,7 +16750,7 @@ Internals.Events = [ var devToolsConfig$jscomp$inline_1891 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-classic-03ed5162", + version: "18.3.0-www-classic-6b9d2287", rendererPackageName: "react-dom" }; (function (internals) { @@ -16788,7 +16794,7 @@ var devToolsConfig$jscomp$inline_1891 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-classic-03ed5162" + reconcilerVersion: "18.3.0-www-classic-6b9d2287" }); assign(Internals, { ReactBrowserEventEmitter: { @@ -17015,7 +17021,7 @@ exports.unstable_renderSubtreeIntoContainer = function ( ); }; exports.unstable_runWithPriority = runWithPriority; -exports.version = "18.3.0-www-classic-03ed5162"; +exports.version = "18.3.0-www-classic-6b9d2287"; /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if ( diff --git a/compiled/facebook-www/ReactDOM-profiling.modern.js b/compiled/facebook-www/ReactDOM-profiling.modern.js index 443b44f075f3e..73f8c9c0b9a67 100644 --- a/compiled/facebook-www/ReactDOM-profiling.modern.js +++ b/compiled/facebook-www/ReactDOM-profiling.modern.js @@ -3445,7 +3445,7 @@ function updateSyncExternalStore(subscribe, getSnapshot) { pushEffect( 9, updateStoreInstance.bind(null, fiber, hook, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); subscribe = workInProgressRoot; @@ -3511,18 +3511,18 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } -function pushEffect(tag, create, destroy, deps) { - tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; +function pushEffect(tag, create, inst, deps) { + tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; null === create ? ((create = createFunctionComponentUpdateQueue()), (currentlyRenderingFiber$1.updateQueue = create), (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy + : ((inst = create.lastEffect), + null === inst ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), + : ((deps = inst.next), + (inst.next = tag), (tag.next = deps), (create.lastEffect = tag))); return tag; @@ -3536,24 +3536,20 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( 1 | hookFlags, create, - void 0, + { destroy: void 0 }, void 0 === deps ? null : deps ); } function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); deps = void 0 === deps ? null : deps; - var destroy = void 0; - if (null !== currentHook) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); - return; - } - } - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); + var inst = hook.memoizedState.inst; + null !== currentHook && + null !== deps && + areHookInputsEqual(deps, currentHook.memoizedState.deps) + ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) + : ((currentlyRenderingFiber$1.flags |= fiberFlags), + (hook.memoizedState = pushEffect(1 | hookFlags, create, inst, deps))); } function mountEffect(create, deps) { mountEffectImpl(8390656, 8, create, deps); @@ -3917,7 +3913,7 @@ var HooksDispatcherOnMount = { getServerSnapshot, getSnapshot ), - void 0, + { destroy: void 0 }, null ); return getServerSnapshot; @@ -7382,10 +7378,11 @@ function commitHookEffectListUnmount( var effect = (updateQueue = updateQueue.next); do { if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; + var inst = effect.inst, + destroy = inst.destroy; void 0 !== destroy && - (enableSchedulingProfiler && + ((inst.destroy = void 0), + enableSchedulingProfiler && (0 !== (flags & 8) ? enableSchedulingProfiler && null !== injectedProfilingHooks && @@ -7435,8 +7432,10 @@ function commitHookEffectListMount(flags, finishedWork) { injectedProfilingHooks.markComponentLayoutEffectMountStarted( finishedWork )); - var create = effect.create; - effect.destroy = create(); + var create = effect.create, + inst = effect.inst; + create = create(); + inst.destroy = create; enableSchedulingProfiler && (0 !== (flags & 8) ? enableSchedulingProfiler && @@ -8103,28 +8102,35 @@ function commitDeletionEffectsOnFiber( ) { prevHostParentIsContainer = prevHostParent = prevHostParent.next; do { - var _effect = prevHostParentIsContainer, - destroy = _effect.destroy; - _effect = _effect.tag; + var tag = prevHostParentIsContainer.tag, + inst = prevHostParentIsContainer.inst, + destroy = inst.destroy; void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && + (0 !== (tag & 2) + ? ((inst.destroy = void 0), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + )) + : 0 !== (tag & 4) && (enableSchedulingProfiler && markComponentLayoutEffectUnmountStarted(deletedFiber), shouldProfile(deletedFiber) ? (startLayoutEffectTimer(), + (inst.destroy = void 0), safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy ), recordLayoutEffectDuration(deletedFiber)) - : safelyCallDestroy( + : ((inst.destroy = void 0), + safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy - ), + )), enableSchedulingProfiler && markComponentLayoutEffectUnmountStopped())); prevHostParentIsContainer = prevHostParentIsContainer.next; @@ -16265,7 +16271,7 @@ Internals.Events = [ var devToolsConfig$jscomp$inline_1849 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-modern-2e9b50ad", + version: "18.3.0-www-modern-5bd76b04", rendererPackageName: "react-dom" }; (function (internals) { @@ -16310,7 +16316,7 @@ var devToolsConfig$jscomp$inline_1849 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-modern-2e9b50ad" + reconcilerVersion: "18.3.0-www-modern-5bd76b04" }); exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; exports.createPortal = function (children, container) { @@ -16466,7 +16472,7 @@ exports.unstable_createEventHandle = function (type, options) { return eventHandle; }; exports.unstable_runWithPriority = runWithPriority; -exports.version = "18.3.0-www-modern-2e9b50ad"; +exports.version = "18.3.0-www-modern-5bd76b04"; /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if ( diff --git a/compiled/facebook-www/ReactDOMTesting-dev.classic.js b/compiled/facebook-www/ReactDOMTesting-dev.classic.js index f5becbd5b44ce..59cafba2846fd 100644 --- a/compiled/facebook-www/ReactDOMTesting-dev.classic.js +++ b/compiled/facebook-www/ReactDOMTesting-dev.classic.js @@ -13437,7 +13437,21 @@ var didWarnAboutUseWrappedInTryCatch; { didWarnAboutMismatchedHooksForComponent = new Set(); didWarnAboutUseWrappedInTryCatch = new Set(); -} // These are set right before calling the component. +} // The effect "instance" is a shared object that remains the same for the entire +// lifetime of an effect. In Rust terms, a RefCell. We use it to store the +// "destroy" function that is returned from an effect, because that is stateful. +// The field is `undefined` if the effect is unmounted, or if the effect ran +// but is not stateful. We don't explicitly track whether the effect is mounted +// or unmounted because that can be inferred by the hiddenness of the fiber in +// the tree, i.e. whether there is a hidden Offscreen fiber above it. +// +// It's unfortunate that this is stored on a separate object, because it adds +// more memory per effect instance, but it's conceptually sound. I think there's +// likely a better data structure we could use for effects; perhaps just one +// array of effect instances per fiber. But I think this is OK for now despite +// the additional memory and we can follow up with performance +// optimizations later. +// These are set right before calling the component. var renderLanes$1 = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. @@ -14780,7 +14794,7 @@ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); return nextSnapshot; @@ -14835,7 +14849,7 @@ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); // Unless we're rendering a blocking lane, schedule a consistency check. // Right before committing, we will walk the tree and check if any of the @@ -14960,11 +14974,11 @@ function rerenderState(initialState) { return rerenderReducer(basicStateReducer); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, inst, deps) { var effect = { tag: tag, create: create, - destroy: destroy, + inst: inst, deps: deps, // Circular next: null @@ -14991,6 +15005,12 @@ function pushEffect(tag, create, destroy, deps) { return effect; } +function createEffectInstance() { + return { + destroy: undefined + }; +} + var stackContainsErrorMessage = null; function getCallerStackFrame() { @@ -15091,7 +15111,7 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - undefined, + createEffectInstance(), nextDeps ); } @@ -15099,17 +15119,16 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - var destroy = undefined; // currentHook is null when rerendering after a render phase state update. + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null when rerendering after a render phase state update. if (currentHook !== null) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); return; } } @@ -15119,7 +15138,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - destroy, + inst, nextDeps ); } @@ -26061,10 +26080,12 @@ function commitHookEffectListUnmount( do { if ((effect.tag & flags) === flags) { // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { + inst.destroy = undefined; + if (enableSchedulingProfiler) { if ((flags & Passive) !== NoFlags) { markComponentPassiveEffectUnmountStarted(finishedWork); @@ -26128,7 +26149,9 @@ function commitHookEffectListMount(flags, finishedWork) { } } - effect.destroy = create(); + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; { if ((flags & Insertion) !== NoFlags) { @@ -26145,8 +26168,6 @@ function commitHookEffectListMount(flags, finishedWork) { } { - var destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { var hookName = void 0; @@ -27627,12 +27648,13 @@ function commitDeletionEffectsOnFiber( var effect = firstEffect; do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -27645,6 +27667,7 @@ function commitDeletionEffectsOnFiber( if (shouldProfile(deletedFiber)) { startLayoutEffectTimer(); + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -27652,6 +27675,7 @@ function commitDeletionEffectsOnFiber( ); recordLayoutEffectDuration(deletedFiber); } else { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -35953,7 +35977,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.3.0-www-classic-53bc944c"; +var ReactVersion = "18.3.0-www-classic-9bbf0cee"; function createPortal$1( children, diff --git a/compiled/facebook-www/ReactDOMTesting-dev.modern.js b/compiled/facebook-www/ReactDOMTesting-dev.modern.js index 8a797739deb6b..e5cae825003fb 100644 --- a/compiled/facebook-www/ReactDOMTesting-dev.modern.js +++ b/compiled/facebook-www/ReactDOMTesting-dev.modern.js @@ -11937,7 +11937,21 @@ var didWarnAboutUseWrappedInTryCatch; { didWarnAboutMismatchedHooksForComponent = new Set(); didWarnAboutUseWrappedInTryCatch = new Set(); -} // These are set right before calling the component. +} // The effect "instance" is a shared object that remains the same for the entire +// lifetime of an effect. In Rust terms, a RefCell. We use it to store the +// "destroy" function that is returned from an effect, because that is stateful. +// The field is `undefined` if the effect is unmounted, or if the effect ran +// but is not stateful. We don't explicitly track whether the effect is mounted +// or unmounted because that can be inferred by the hiddenness of the fiber in +// the tree, i.e. whether there is a hidden Offscreen fiber above it. +// +// It's unfortunate that this is stored on a separate object, because it adds +// more memory per effect instance, but it's conceptually sound. I think there's +// likely a better data structure we could use for effects; perhaps just one +// array of effect instances per fiber. But I think this is OK for now despite +// the additional memory and we can follow up with performance +// optimizations later. +// These are set right before calling the component. var renderLanes$1 = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. @@ -13280,7 +13294,7 @@ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); return nextSnapshot; @@ -13335,7 +13349,7 @@ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); // Unless we're rendering a blocking lane, schedule a consistency check. // Right before committing, we will walk the tree and check if any of the @@ -13460,11 +13474,11 @@ function rerenderState(initialState) { return rerenderReducer(basicStateReducer); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, inst, deps) { var effect = { tag: tag, create: create, - destroy: destroy, + inst: inst, deps: deps, // Circular next: null @@ -13491,6 +13505,12 @@ function pushEffect(tag, create, destroy, deps) { return effect; } +function createEffectInstance() { + return { + destroy: undefined + }; +} + var stackContainsErrorMessage = null; function getCallerStackFrame() { @@ -13591,7 +13611,7 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - undefined, + createEffectInstance(), nextDeps ); } @@ -13599,17 +13619,16 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - var destroy = undefined; // currentHook is null when rerendering after a render phase state update. + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null when rerendering after a render phase state update. if (currentHook !== null) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); return; } } @@ -13619,7 +13638,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - destroy, + inst, nextDeps ); } @@ -24470,10 +24489,12 @@ function commitHookEffectListUnmount( do { if ((effect.tag & flags) === flags) { // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { + inst.destroy = undefined; + if (enableSchedulingProfiler) { if ((flags & Passive) !== NoFlags) { markComponentPassiveEffectUnmountStarted(finishedWork); @@ -24537,7 +24558,9 @@ function commitHookEffectListMount(flags, finishedWork) { } } - effect.destroy = create(); + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; { if ((flags & Insertion) !== NoFlags) { @@ -24554,8 +24577,6 @@ function commitHookEffectListMount(flags, finishedWork) { } { - var destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { var hookName = void 0; @@ -26036,12 +26057,13 @@ function commitDeletionEffectsOnFiber( var effect = firstEffect; do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -26054,6 +26076,7 @@ function commitDeletionEffectsOnFiber( if (shouldProfile(deletedFiber)) { startLayoutEffectTimer(); + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -26061,6 +26084,7 @@ function commitDeletionEffectsOnFiber( ); recordLayoutEffectDuration(deletedFiber); } else { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -34357,7 +34381,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.3.0-www-modern-123e5d07"; +var ReactVersion = "18.3.0-www-modern-b3a1afd3"; function createPortal$1( children, diff --git a/compiled/facebook-www/ReactDOMTesting-prod.classic.js b/compiled/facebook-www/ReactDOMTesting-prod.classic.js index cc42017e7a95a..45773bb8d80c8 100644 --- a/compiled/facebook-www/ReactDOMTesting-prod.classic.js +++ b/compiled/facebook-www/ReactDOMTesting-prod.classic.js @@ -3981,7 +3981,7 @@ function updateSyncExternalStore(subscribe, getSnapshot) { pushEffect( 9, updateStoreInstance.bind(null, fiber, hook, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); subscribe = workInProgressRoot; @@ -4047,18 +4047,18 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } -function pushEffect(tag, create, destroy, deps) { - tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; +function pushEffect(tag, create, inst, deps) { + tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; null === create ? ((create = createFunctionComponentUpdateQueue()), (currentlyRenderingFiber$1.updateQueue = create), (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy + : ((inst = create.lastEffect), + null === inst ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), + : ((deps = inst.next), + (inst.next = tag), (tag.next = deps), (create.lastEffect = tag))); return tag; @@ -4072,24 +4072,20 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( 1 | hookFlags, create, - void 0, + { destroy: void 0 }, void 0 === deps ? null : deps ); } function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); deps = void 0 === deps ? null : deps; - var destroy = void 0; - if (null !== currentHook) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); - return; - } - } - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); + var inst = hook.memoizedState.inst; + null !== currentHook && + null !== deps && + areHookInputsEqual(deps, currentHook.memoizedState.deps) + ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) + : ((currentlyRenderingFiber$1.flags |= fiberFlags), + (hook.memoizedState = pushEffect(1 | hookFlags, create, inst, deps))); } function mountEffect(create, deps) { mountEffectImpl(8390656, 8, create, deps); @@ -4451,7 +4447,7 @@ var HooksDispatcherOnMount = { getServerSnapshot, getSnapshot ), - void 0, + { destroy: void 0 }, null ); return getServerSnapshot; @@ -7777,10 +7773,11 @@ function commitHookEffectListUnmount( var effect = (updateQueue = updateQueue.next); do { if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; + var inst = effect.inst, + destroy = inst.destroy; void 0 !== destroy && - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + ((inst.destroy = void 0), + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy)); } effect = effect.next; } while (effect !== updateQueue); @@ -7793,8 +7790,10 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create = effect.create; - effect.destroy = create(); + var create = effect.create, + inst = effect.inst; + create = create(); + inst.destroy = create; } effect = effect.next; } while (effect !== finishedWork); @@ -8339,18 +8338,24 @@ function commitDeletionEffectsOnFiber( ) { prevHostParentIsContainer = prevHostParent = prevHostParent.next; do { - var _effect = prevHostParentIsContainer, - destroy = _effect.destroy; - _effect = _effect.tag; + var tag = prevHostParentIsContainer.tag, + inst = prevHostParentIsContainer.inst, + destroy = inst.destroy; void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && + (0 !== (tag & 2) + ? ((inst.destroy = void 0), safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy - )); + )) + : 0 !== (tag & 4) && + ((inst.destroy = void 0), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ))); prevHostParentIsContainer = prevHostParentIsContainer.next; } while (prevHostParentIsContainer !== prevHostParent); } @@ -14658,7 +14663,7 @@ Internals.Events = [ var devToolsConfig$jscomp$inline_1769 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-classic-ccedb28a", + version: "18.3.0-www-classic-cd98b4c3", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2238 = { @@ -14688,7 +14693,7 @@ var internals$jscomp$inline_2238 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-classic-ccedb28a" + reconcilerVersion: "18.3.0-www-classic-cd98b4c3" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2239 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -16720,4 +16725,4 @@ exports.unstable_renderSubtreeIntoContainer = function ( ); }; exports.unstable_runWithPriority = runWithPriority; -exports.version = "18.3.0-www-classic-ccedb28a"; +exports.version = "18.3.0-www-classic-cd98b4c3"; diff --git a/compiled/facebook-www/ReactDOMTesting-prod.modern.js b/compiled/facebook-www/ReactDOMTesting-prod.modern.js index ef3052022f2b2..56129a5988569 100644 --- a/compiled/facebook-www/ReactDOMTesting-prod.modern.js +++ b/compiled/facebook-www/ReactDOMTesting-prod.modern.js @@ -3442,7 +3442,7 @@ function updateSyncExternalStore(subscribe, getSnapshot) { pushEffect( 9, updateStoreInstance.bind(null, fiber, hook, nextSnapshot, getSnapshot), - void 0, + { destroy: void 0 }, null ); subscribe = workInProgressRoot; @@ -3508,18 +3508,18 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } -function pushEffect(tag, create, destroy, deps) { - tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; +function pushEffect(tag, create, inst, deps) { + tag = { tag: tag, create: create, inst: inst, deps: deps, next: null }; create = currentlyRenderingFiber$1.updateQueue; null === create ? ((create = createFunctionComponentUpdateQueue()), (currentlyRenderingFiber$1.updateQueue = create), (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy + : ((inst = create.lastEffect), + null === inst ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), + : ((deps = inst.next), + (inst.next = tag), (tag.next = deps), (create.lastEffect = tag))); return tag; @@ -3533,24 +3533,20 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( 1 | hookFlags, create, - void 0, + { destroy: void 0 }, void 0 === deps ? null : deps ); } function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); deps = void 0 === deps ? null : deps; - var destroy = void 0; - if (null !== currentHook) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); - return; - } - } - currentlyRenderingFiber$1.flags |= fiberFlags; - hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); + var inst = hook.memoizedState.inst; + null !== currentHook && + null !== deps && + areHookInputsEqual(deps, currentHook.memoizedState.deps) + ? (hook.memoizedState = pushEffect(hookFlags, create, inst, deps)) + : ((currentlyRenderingFiber$1.flags |= fiberFlags), + (hook.memoizedState = pushEffect(1 | hookFlags, create, inst, deps))); } function mountEffect(create, deps) { mountEffectImpl(8390656, 8, create, deps); @@ -3912,7 +3908,7 @@ var HooksDispatcherOnMount = { getServerSnapshot, getSnapshot ), - void 0, + { destroy: void 0 }, null ); return getServerSnapshot; @@ -7181,10 +7177,11 @@ function commitHookEffectListUnmount( var effect = (updateQueue = updateQueue.next); do { if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; + var inst = effect.inst, + destroy = inst.destroy; void 0 !== destroy && - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + ((inst.destroy = void 0), + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy)); } effect = effect.next; } while (effect !== updateQueue); @@ -7197,8 +7194,10 @@ function commitHookEffectListMount(flags, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & flags) === flags) { - var create = effect.create; - effect.destroy = create(); + var create = effect.create, + inst = effect.inst; + create = create(); + inst.destroy = create; } effect = effect.next; } while (effect !== finishedWork); @@ -7743,18 +7742,24 @@ function commitDeletionEffectsOnFiber( ) { prevHostParentIsContainer = prevHostParent = prevHostParent.next; do { - var _effect = prevHostParentIsContainer, - destroy = _effect.destroy; - _effect = _effect.tag; + var tag = prevHostParentIsContainer.tag, + inst = prevHostParentIsContainer.inst, + destroy = inst.destroy; void 0 !== destroy && - (0 !== (_effect & 2) - ? safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy) - : 0 !== (_effect & 4) && + (0 !== (tag & 2) + ? ((inst.destroy = void 0), safelyCallDestroy( deletedFiber, nearestMountedAncestor, destroy - )); + )) + : 0 !== (tag & 4) && + ((inst.destroy = void 0), + safelyCallDestroy( + deletedFiber, + nearestMountedAncestor, + destroy + ))); prevHostParentIsContainer = prevHostParentIsContainer.next; } while (prevHostParentIsContainer !== prevHostParent); } @@ -15881,7 +15886,7 @@ Internals.Events = [ var devToolsConfig$jscomp$inline_1799 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-modern-b6a03dc1", + version: "18.3.0-www-modern-c1d269df", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2205 = { @@ -15912,7 +15917,7 @@ var internals$jscomp$inline_2205 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-modern-b6a03dc1" + reconcilerVersion: "18.3.0-www-modern-c1d269df" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2206 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -16232,4 +16237,4 @@ exports.unstable_createEventHandle = function (type, options) { return eventHandle; }; exports.unstable_runWithPriority = runWithPriority; -exports.version = "18.3.0-www-modern-b6a03dc1"; +exports.version = "18.3.0-www-modern-c1d269df"; diff --git a/compiled/facebook-www/ReactTestRenderer-dev.classic.js b/compiled/facebook-www/ReactTestRenderer-dev.classic.js index 8227a062150d3..4d8937eca6f2b 100644 --- a/compiled/facebook-www/ReactTestRenderer-dev.classic.js +++ b/compiled/facebook-www/ReactTestRenderer-dev.classic.js @@ -6315,7 +6315,21 @@ var didWarnAboutUseWrappedInTryCatch; { didWarnAboutMismatchedHooksForComponent = new Set(); didWarnAboutUseWrappedInTryCatch = new Set(); -} // These are set right before calling the component. +} // The effect "instance" is a shared object that remains the same for the entire +// lifetime of an effect. In Rust terms, a RefCell. We use it to store the +// "destroy" function that is returned from an effect, because that is stateful. +// The field is `undefined` if the effect is unmounted, or if the effect ran +// but is not stateful. We don't explicitly track whether the effect is mounted +// or unmounted because that can be inferred by the hiddenness of the fiber in +// the tree, i.e. whether there is a hidden Offscreen fiber above it. +// +// It's unfortunate that this is stored on a separate object, because it adds +// more memory per effect instance, but it's conceptually sound. I think there's +// likely a better data structure we could use for effects; perhaps just one +// array of effect instances per fiber. But I think this is OK for now despite +// the additional memory and we can follow up with performance +// optimizations later. +// These are set right before calling the component. var renderLanes$1 = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. @@ -7517,7 +7531,7 @@ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); return nextSnapshot; @@ -7572,7 +7586,7 @@ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); // Unless we're rendering a blocking lane, schedule a consistency check. // Right before committing, we will walk the tree and check if any of the @@ -7697,11 +7711,11 @@ function rerenderState(initialState) { return rerenderReducer(basicStateReducer); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, inst, deps) { var effect = { tag: tag, create: create, - destroy: destroy, + inst: inst, deps: deps, // Circular next: null @@ -7728,6 +7742,12 @@ function pushEffect(tag, create, destroy, deps) { return effect; } +function createEffectInstance() { + return { + destroy: undefined + }; +} + function mountRef(initialValue) { var hook = mountWorkInProgressHook(); @@ -7752,7 +7772,7 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - undefined, + createEffectInstance(), nextDeps ); } @@ -7760,17 +7780,16 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - var destroy = undefined; // currentHook is null when rerendering after a render phase state update. + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null when rerendering after a render phase state update. if (currentHook !== null) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); return; } } @@ -7780,7 +7799,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - destroy, + inst, nextDeps ); } @@ -16794,10 +16813,12 @@ function commitHookEffectListUnmount( do { if ((effect.tag & flags) === flags) { // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { + inst.destroy = undefined; + { if ((flags & Insertion) !== NoFlags) { setIsRunningInsertionEffect(true); @@ -16837,7 +16858,9 @@ function commitHookEffectListMount(flags, finishedWork) { } } - effect.destroy = create(); + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; { if ((flags & Insertion) !== NoFlags) { @@ -16846,8 +16869,6 @@ function commitHookEffectListMount(flags, finishedWork) { } { - var destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { var hookName = void 0; @@ -17952,12 +17973,13 @@ function commitDeletionEffectsOnFiber( var effect = firstEffect; do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -17966,6 +17988,7 @@ function commitDeletionEffectsOnFiber( } else if ((tag & Layout) !== NoFlags) { if (shouldProfile(deletedFiber)) { startLayoutEffectTimer(); + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -17973,6 +17996,7 @@ function commitDeletionEffectsOnFiber( ); recordLayoutEffectDuration(deletedFiber); } else { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -24497,7 +24521,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.3.0-www-classic-9a6e0a7c"; +var ReactVersion = "18.3.0-www-classic-ce5b9a0a"; // Might add PROFILE later. diff --git a/compiled/facebook-www/ReactTestRenderer-dev.modern.js b/compiled/facebook-www/ReactTestRenderer-dev.modern.js index e465981e65338..b831f7d20b9f5 100644 --- a/compiled/facebook-www/ReactTestRenderer-dev.modern.js +++ b/compiled/facebook-www/ReactTestRenderer-dev.modern.js @@ -6315,7 +6315,21 @@ var didWarnAboutUseWrappedInTryCatch; { didWarnAboutMismatchedHooksForComponent = new Set(); didWarnAboutUseWrappedInTryCatch = new Set(); -} // These are set right before calling the component. +} // The effect "instance" is a shared object that remains the same for the entire +// lifetime of an effect. In Rust terms, a RefCell. We use it to store the +// "destroy" function that is returned from an effect, because that is stateful. +// The field is `undefined` if the effect is unmounted, or if the effect ran +// but is not stateful. We don't explicitly track whether the effect is mounted +// or unmounted because that can be inferred by the hiddenness of the fiber in +// the tree, i.e. whether there is a hidden Offscreen fiber above it. +// +// It's unfortunate that this is stored on a separate object, because it adds +// more memory per effect instance, but it's conceptually sound. I think there's +// likely a better data structure we could use for effects; perhaps just one +// array of effect instances per fiber. But I think this is OK for now despite +// the additional memory and we can follow up with performance +// optimizations later. +// These are set right before calling the component. var renderLanes$1 = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. @@ -7517,7 +7531,7 @@ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); return nextSnapshot; @@ -7572,7 +7586,7 @@ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { pushEffect( HasEffect | Passive, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), - undefined, + createEffectInstance(), null ); // Unless we're rendering a blocking lane, schedule a consistency check. // Right before committing, we will walk the tree and check if any of the @@ -7697,11 +7711,11 @@ function rerenderState(initialState) { return rerenderReducer(basicStateReducer); } -function pushEffect(tag, create, destroy, deps) { +function pushEffect(tag, create, inst, deps) { var effect = { tag: tag, create: create, - destroy: destroy, + inst: inst, deps: deps, // Circular next: null @@ -7728,6 +7742,12 @@ function pushEffect(tag, create, destroy, deps) { return effect; } +function createEffectInstance() { + return { + destroy: undefined + }; +} + function mountRef(initialValue) { var hook = mountWorkInProgressHook(); @@ -7752,7 +7772,7 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - undefined, + createEffectInstance(), nextDeps ); } @@ -7760,17 +7780,16 @@ function mountEffectImpl(fiberFlags, hookFlags, create, deps) { function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - var destroy = undefined; // currentHook is null when rerendering after a render phase state update. + var effect = hook.memoizedState; + var inst = effect.inst; // currentHook is null when rerendering after a render phase state update. if (currentHook !== null) { - var prevEffect = currentHook.memoizedState; - destroy = prevEffect.destroy; - if (nextDeps !== null) { + var prevEffect = currentHook.memoizedState; var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, inst, nextDeps); return; } } @@ -7780,7 +7799,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect( HasEffect | hookFlags, create, - destroy, + inst, nextDeps ); } @@ -16794,10 +16813,12 @@ function commitHookEffectListUnmount( do { if ((effect.tag & flags) === flags) { // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { + inst.destroy = undefined; + { if ((flags & Insertion) !== NoFlags) { setIsRunningInsertionEffect(true); @@ -16837,7 +16858,9 @@ function commitHookEffectListMount(flags, finishedWork) { } } - effect.destroy = create(); + var inst = effect.inst; + var destroy = create(); + inst.destroy = destroy; { if ((flags & Insertion) !== NoFlags) { @@ -16846,8 +16869,6 @@ function commitHookEffectListMount(flags, finishedWork) { } { - var destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { var hookName = void 0; @@ -17952,12 +17973,13 @@ function commitDeletionEffectsOnFiber( var effect = firstEffect; do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + var tag = effect.tag; + var inst = effect.inst; + var destroy = inst.destroy; if (destroy !== undefined) { if ((tag & Insertion) !== NoFlags) { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -17966,6 +17988,7 @@ function commitDeletionEffectsOnFiber( } else if ((tag & Layout) !== NoFlags) { if (shouldProfile(deletedFiber)) { startLayoutEffectTimer(); + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -17973,6 +17996,7 @@ function commitDeletionEffectsOnFiber( ); recordLayoutEffectDuration(deletedFiber); } else { + inst.destroy = undefined; safelyCallDestroy( deletedFiber, nearestMountedAncestor, @@ -24497,7 +24521,7 @@ function createFiberRoot( return root; } -var ReactVersion = "18.3.0-www-modern-b6a03dc1"; +var ReactVersion = "18.3.0-www-modern-c1d269df"; // Might add PROFILE later.