From 9f66192fd2d91882968ebe2c2e13f7018c6232cb Mon Sep 17 00:00:00 2001 From: acdlite Date: Fri, 31 May 2024 21:57:58 +0000 Subject: [PATCH] Fix: `useTransition` after `use` gets stuck in pending state (#29670) When a component suspends with `use`, we switch to the "re-render" dispatcher during the subsequent render attempt, so that we can reuse the work from the initial attempt. However, once we run out of hooks from the previous attempt, we should switch back to the regular "update" dispatcher. This is conceptually the same fix as the one introduced in https://github.com/facebook/react/pull/26232. That fix only accounted for initial mount, but the useTransition regression test added in f82973302b3f490ec120c3b102e8c3792452dfc9 illustrates that we need to handle updates, too. The issue affects more than just useTransition but because most of the behavior between the "re-render" and "update" dispatchers is the same it's hard to contrive other scenarios in a test, which is probably why it took so long for someone to notice. Closes #28923 and #29209 --------- Co-authored-by: eps1lon DiffTrain build for commit https://github.com/facebook/react/commit/adbec0c25aff07f04b0678679554505ba2813168. --- .../cjs/ReactTestRenderer-dev.js | 42 +++++++++++++++---- .../cjs/ReactTestRenderer-prod.js | 19 +++++---- .../cjs/ReactTestRenderer-profiling.js | 19 +++++---- .../vendor/react/react/cjs/React-dev.js | 4 +- .../vendor/react/react/cjs/React-prod.js | 4 +- .../vendor/react/react/cjs/React-profiling.js | 4 +- .../Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.fb.js | 42 +++++++++++++++---- .../implementations/ReactFabric-prod.fb.js | 19 +++++---- .../ReactFabric-profiling.fb.js | 19 +++++---- .../ReactNativeRenderer-dev.fb.js | 42 +++++++++++++++---- .../ReactNativeRenderer-prod.fb.js | 23 ++++++---- .../ReactNativeRenderer-profiling.fb.js | 23 ++++++---- 13 files changed, 182 insertions(+), 80 deletions(-) diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js index 56b260b145..02c0ead0c8 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<75b6042ec2df1ed24f9d3d5c89c9b994>> + * @generated SignedSource<<843340fb623449714d5807ec34c388a7>> */ 'use strict'; @@ -7843,15 +7843,39 @@ function useThenable(thenable) { thenableState = createThenableState(); } - var result = trackUsedThenable(thenableState, thenable, index); + var result = trackUsedThenable(thenableState, thenable, index); // When something suspends with `use`, we replay the component with the + // "re-render" dispatcher instead of the "mount" or "update" dispatcher. + // + // But if there are additional hooks that occur after the `use` invocation + // that suspended, they wouldn't have been processed during the previous + // attempt. So after we invoke `use` again, we may need to switch from the + // "re-render" dispatcher back to the "mount" or "update" dispatcher. That's + // what the following logic accounts for. + // + // TODO: Theoretically this logic only needs to go into the rerender + // dispatcher. Could optimize, but probably not be worth it. + // This is the same logic as in updateWorkInProgressHook. + + var workInProgressFiber = currentlyRenderingFiber$1; + var nextWorkInProgressHook = workInProgressHook === null ? // We're at the beginning of the list, so read from the first hook from + // the fiber. + workInProgressFiber.memoizedState : workInProgressHook.next; + + if (nextWorkInProgressHook !== null) ; else { + // There are no remaining hooks from the previous attempt. We're no longer + // in "re-render" mode. Switch to the normal mount or update dispatcher. + // + // This is the same as the logic in renderWithHooks, except we don't bother + // to track the hook types debug information in this case (sufficient to + // only do that when nothing suspends). + var currentFiber = workInProgressFiber.alternate; - if (currentlyRenderingFiber$1.alternate === null && (workInProgressHook === null ? currentlyRenderingFiber$1.memoizedState === null : workInProgressHook.next === null)) { - // Initial render, and either this is the first time the component is - // called, or there were no Hooks called after this use() the previous - // time (perhaps because it threw). Subsequent Hook calls should use the - // mount dispatcher. { - ReactSharedInternals.H = HooksDispatcherOnMountInDEV; + if (currentFiber !== null && currentFiber.memoizedState !== null) { + ReactSharedInternals.H = HooksDispatcherOnUpdateInDEV; + } else { + ReactSharedInternals.H = HooksDispatcherOnMountInDEV; + } } } @@ -23471,7 +23495,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-5c420e3824-20240531'; +var ReactVersion = '19.0.0-rc-adbec0c25a-20240531'; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js index bd9cf29c0f..27ce63194f 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<0c59fb69281d1d909e6de56cf4430600>> + * @generated SignedSource<<905cc175856264e313ce8da1a2a4238b>> */ "use strict"; @@ -2478,11 +2478,16 @@ function useThenable(thenable) { thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - null === currentlyRenderingFiber$1.alternate && + index = currentlyRenderingFiber$1; + null === (null === workInProgressHook - ? null === currentlyRenderingFiber$1.memoizedState - : null === workInProgressHook.next) && - (ReactSharedInternals.H = HooksDispatcherOnMount); + ? index.memoizedState + : workInProgressHook.next) && + ((index = index.alternate), + (ReactSharedInternals.H = + null === index || null === index.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate)); return thenable; } function use(usable) { @@ -9298,7 +9303,7 @@ var devToolsConfig$jscomp$inline_1047 = { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "19.0.0-rc-5c420e3824-20240531", + version: "19.0.0-rc-adbec0c25a-20240531", rendererPackageName: "react-test-renderer" }; var internals$jscomp$inline_1234 = { @@ -9329,7 +9334,7 @@ var internals$jscomp$inline_1234 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-5c420e3824-20240531" + reconcilerVersion: "19.0.0-rc-adbec0c25a-20240531" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1235 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js index d41b88af40..8ebec1af32 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<0a4e2053c331cd297df75b0c0a284142>> + * @generated SignedSource<<2ec503c3ec9cc5ba080608bcfdeb069e>> */ "use strict"; @@ -2566,11 +2566,16 @@ function useThenable(thenable) { thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - null === currentlyRenderingFiber$1.alternate && + index = currentlyRenderingFiber$1; + null === (null === workInProgressHook - ? null === currentlyRenderingFiber$1.memoizedState - : null === workInProgressHook.next) && - (ReactSharedInternals.H = HooksDispatcherOnMount); + ? index.memoizedState + : workInProgressHook.next) && + ((index = index.alternate), + (ReactSharedInternals.H = + null === index || null === index.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate)); return thenable; } function use(usable) { @@ -9920,7 +9925,7 @@ var devToolsConfig$jscomp$inline_1130 = { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "19.0.0-rc-5c420e3824-20240531", + version: "19.0.0-rc-adbec0c25a-20240531", rendererPackageName: "react-test-renderer" }; (function (internals) { @@ -9964,7 +9969,7 @@ var devToolsConfig$jscomp$inline_1130 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-5c420e3824-20240531" + reconcilerVersion: "19.0.0-rc-adbec0c25a-20240531" }); exports._Scheduler = Scheduler; exports.act = act; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js index 603550aa05..4de81ef9bc 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<7e91f8a3315accc44974ba6d3012b60f>> + * @generated SignedSource<<4f7e50456e26afbb6944fc28181daa80>> */ 'use strict'; @@ -24,7 +24,7 @@ if ( } var dynamicFlagsUntyped = require('ReactNativeInternalFeatureFlags'); -var ReactVersion = '19.0.0-rc-5c420e3824-20240531'; +var ReactVersion = '19.0.0-rc-adbec0c25a-20240531'; // Re-export dynamic flags from the internal module. var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js index 4120723721..6aeb446a64 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<2a9cffe28b099cbbf68478af1f393ff1>> + * @generated SignedSource<> */ "use strict"; @@ -604,4 +604,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-rc-5c420e3824-20240531"; +exports.version = "19.0.0-rc-adbec0c25a-20240531"; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js index 3caa76b5a3..1a2965efb7 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<8ec2a6bbcfd86d30090ddd12c98add78>> + * @generated SignedSource<<9f5c8cb9b979f6b6f6c25611a0886ae3>> */ "use strict"; @@ -608,7 +608,7 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-rc-5c420e3824-20240531"; +exports.version = "19.0.0-rc-adbec0c25a-20240531"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION index 2056bc48c8..b38500661f 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION @@ -1 +1 @@ -5c420e3824859b33321b4bc9ce3119806fac56c2 +adbec0c25aff07f04b0678679554505ba2813168 diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index fc73dd2d15..4042f60ecf 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<9b439e19fdffa2fa6e386a55c7f2dc88>> + * @generated SignedSource<<959db6b7a430088709ef79d2031321cd>> */ 'use strict'; @@ -10583,15 +10583,39 @@ function useThenable(thenable) { thenableState = createThenableState(); } - var result = trackUsedThenable(thenableState, thenable, index); + var result = trackUsedThenable(thenableState, thenable, index); // When something suspends with `use`, we replay the component with the + // "re-render" dispatcher instead of the "mount" or "update" dispatcher. + // + // But if there are additional hooks that occur after the `use` invocation + // that suspended, they wouldn't have been processed during the previous + // attempt. So after we invoke `use` again, we may need to switch from the + // "re-render" dispatcher back to the "mount" or "update" dispatcher. That's + // what the following logic accounts for. + // + // TODO: Theoretically this logic only needs to go into the rerender + // dispatcher. Could optimize, but probably not be worth it. + // This is the same logic as in updateWorkInProgressHook. + + var workInProgressFiber = currentlyRenderingFiber$1; + var nextWorkInProgressHook = workInProgressHook === null ? // We're at the beginning of the list, so read from the first hook from + // the fiber. + workInProgressFiber.memoizedState : workInProgressHook.next; + + if (nextWorkInProgressHook !== null) ; else { + // There are no remaining hooks from the previous attempt. We're no longer + // in "re-render" mode. Switch to the normal mount or update dispatcher. + // + // This is the same as the logic in renderWithHooks, except we don't bother + // to track the hook types debug information in this case (sufficient to + // only do that when nothing suspends). + var currentFiber = workInProgressFiber.alternate; - if (currentlyRenderingFiber$1.alternate === null && (workInProgressHook === null ? currentlyRenderingFiber$1.memoizedState === null : workInProgressHook.next === null)) { - // Initial render, and either this is the first time the component is - // called, or there were no Hooks called after this use() the previous - // time (perhaps because it threw). Subsequent Hook calls should use the - // mount dispatcher. { - ReactSharedInternals.H = HooksDispatcherOnMountInDEV; + if (currentFiber !== null && currentFiber.memoizedState !== null) { + ReactSharedInternals.H = HooksDispatcherOnUpdateInDEV; + } else { + ReactSharedInternals.H = HooksDispatcherOnMountInDEV; + } } } @@ -26206,7 +26230,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-5c420e3824-20240531'; +var ReactVersion = '19.0.0-rc-adbec0c25a-20240531'; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 250846dcd1..98ac794f5a 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<183c26ead26dbc699a54a97554f63097>> + * @generated SignedSource<> */ "use strict"; @@ -3857,11 +3857,16 @@ function useThenable(thenable) { thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - null === currentlyRenderingFiber$1.alternate && + index = currentlyRenderingFiber$1; + null === (null === workInProgressHook - ? null === currentlyRenderingFiber$1.memoizedState - : null === workInProgressHook.next) && - (ReactSharedInternals.H = HooksDispatcherOnMount); + ? index.memoizedState + : workInProgressHook.next) && + ((index = index.alternate), + (ReactSharedInternals.H = + null === index || null === index.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate)); return thenable; } function use(usable) { @@ -10551,7 +10556,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1124 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-5c420e3824-20240531", + version: "19.0.0-rc-adbec0c25a-20240531", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10594,7 +10599,7 @@ var internals$jscomp$inline_1350 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-5c420e3824-20240531" + reconcilerVersion: "19.0.0-rc-adbec0c25a-20240531" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1351 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index dad24591f6..8096c4cf4b 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<8ccb12c6c371309a0a428e1772ab27d6>> */ "use strict"; @@ -3979,11 +3979,16 @@ function useThenable(thenable) { thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - null === currentlyRenderingFiber$1.alternate && + index = currentlyRenderingFiber$1; + null === (null === workInProgressHook - ? null === currentlyRenderingFiber$1.memoizedState - : null === workInProgressHook.next) && - (ReactSharedInternals.H = HooksDispatcherOnMount); + ? index.memoizedState + : workInProgressHook.next) && + ((index = index.alternate), + (ReactSharedInternals.H = + null === index || null === index.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate)); return thenable; } function use(usable) { @@ -11257,7 +11262,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1205 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-5c420e3824-20240531", + version: "19.0.0-rc-adbec0c25a-20240531", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -11313,7 +11318,7 @@ var roots = new Map(), scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-5c420e3824-20240531" + reconcilerVersion: "19.0.0-rc-adbec0c25a-20240531" }); exports.createPortal = function (children, containerTag) { return createPortal$1( diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index a6dac358b2..4734b1ee28 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<2f599e53bfb1d0ee6eaf5cd63bae3a13>> */ 'use strict'; @@ -10766,15 +10766,39 @@ function useThenable(thenable) { thenableState = createThenableState(); } - var result = trackUsedThenable(thenableState, thenable, index); + var result = trackUsedThenable(thenableState, thenable, index); // When something suspends with `use`, we replay the component with the + // "re-render" dispatcher instead of the "mount" or "update" dispatcher. + // + // But if there are additional hooks that occur after the `use` invocation + // that suspended, they wouldn't have been processed during the previous + // attempt. So after we invoke `use` again, we may need to switch from the + // "re-render" dispatcher back to the "mount" or "update" dispatcher. That's + // what the following logic accounts for. + // + // TODO: Theoretically this logic only needs to go into the rerender + // dispatcher. Could optimize, but probably not be worth it. + // This is the same logic as in updateWorkInProgressHook. + + var workInProgressFiber = currentlyRenderingFiber$1; + var nextWorkInProgressHook = workInProgressHook === null ? // We're at the beginning of the list, so read from the first hook from + // the fiber. + workInProgressFiber.memoizedState : workInProgressHook.next; + + if (nextWorkInProgressHook !== null) ; else { + // There are no remaining hooks from the previous attempt. We're no longer + // in "re-render" mode. Switch to the normal mount or update dispatcher. + // + // This is the same as the logic in renderWithHooks, except we don't bother + // to track the hook types debug information in this case (sufficient to + // only do that when nothing suspends). + var currentFiber = workInProgressFiber.alternate; - if (currentlyRenderingFiber$1.alternate === null && (workInProgressHook === null ? currentlyRenderingFiber$1.memoizedState === null : workInProgressHook.next === null)) { - // Initial render, and either this is the first time the component is - // called, or there were no Hooks called after this use() the previous - // time (perhaps because it threw). Subsequent Hook calls should use the - // mount dispatcher. { - ReactSharedInternals.H = HooksDispatcherOnMountInDEV; + if (currentFiber !== null && currentFiber.memoizedState !== null) { + ReactSharedInternals.H = HooksDispatcherOnUpdateInDEV; + } else { + ReactSharedInternals.H = HooksDispatcherOnMountInDEV; + } } } @@ -26562,7 +26586,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-5c420e3824-20240531'; +var ReactVersion = '19.0.0-rc-adbec0c25a-20240531'; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index d701d57096..db3773cb7e 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<94353ed0f6f05f5f4d4ab74ba4240e98>> + * @generated SignedSource<<397a4e89bef38724e564db4d5df7d186>> */ "use strict"; @@ -3879,11 +3879,16 @@ function useThenable(thenable) { thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - null === currentlyRenderingFiber$1.alternate && + index = currentlyRenderingFiber$1; + null === (null === workInProgressHook - ? null === currentlyRenderingFiber$1.memoizedState - : null === workInProgressHook.next) && - (ReactSharedInternals.H = HooksDispatcherOnMount); + ? index.memoizedState + : workInProgressHook.next) && + ((index = index.alternate), + (ReactSharedInternals.H = + null === index || null === index.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate)); return thenable; } function use(usable) { @@ -10696,11 +10701,11 @@ function traverseOwnerTreeUp(hierarchy, instance) { traverseOwnerTreeUp(hierarchy, instance); } var isomorphicReactPackageVersion = React.version; -if ("19.0.0-rc-5c420e3824-20240531" !== isomorphicReactPackageVersion) +if ("19.0.0-rc-adbec0c25a-20240531" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-native-renderer" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-native-renderer: 19.0.0-rc-5c420e3824-20240531\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-native-renderer: 19.0.0-rc-adbec0c25a-20240531\nLearn more: https://react.dev/warnings/version-mismatch") ); if ( "function" !== @@ -10750,7 +10755,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1192 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "19.0.0-rc-5c420e3824-20240531", + version: "19.0.0-rc-adbec0c25a-20240531", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10793,7 +10798,7 @@ var internals$jscomp$inline_1439 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-5c420e3824-20240531" + reconcilerVersion: "19.0.0-rc-adbec0c25a-20240531" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1440 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 6113510220..967ca17310 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<75a5028640a4a5d0e637c6be72a8cf5a>> */ "use strict"; @@ -4001,11 +4001,16 @@ function useThenable(thenable) { thenableIndexCounter += 1; null === thenableState && (thenableState = []); thenable = trackUsedThenable(thenableState, thenable, index); - null === currentlyRenderingFiber$1.alternate && + index = currentlyRenderingFiber$1; + null === (null === workInProgressHook - ? null === currentlyRenderingFiber$1.memoizedState - : null === workInProgressHook.next) && - (ReactSharedInternals.H = HooksDispatcherOnMount); + ? index.memoizedState + : workInProgressHook.next) && + ((index = index.alternate), + (ReactSharedInternals.H = + null === index || null === index.memoizedState + ? HooksDispatcherOnMount + : HooksDispatcherOnUpdate)); return thenable; } function use(usable) { @@ -11403,11 +11408,11 @@ function traverseOwnerTreeUp(hierarchy, instance) { traverseOwnerTreeUp(hierarchy, instance); } var isomorphicReactPackageVersion = React.version; -if ("19.0.0-rc-5c420e3824-20240531" !== isomorphicReactPackageVersion) +if ("19.0.0-rc-adbec0c25a-20240531" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-native-renderer" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-native-renderer: 19.0.0-rc-5c420e3824-20240531\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-native-renderer: 19.0.0-rc-adbec0c25a-20240531\nLearn more: https://react.dev/warnings/version-mismatch") ); if ( "function" !== @@ -11457,7 +11462,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1273 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "19.0.0-rc-5c420e3824-20240531", + version: "19.0.0-rc-adbec0c25a-20240531", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -11513,7 +11518,7 @@ var roots = new Map(), scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-5c420e3824-20240531" + reconcilerVersion: "19.0.0-rc-adbec0c25a-20240531" }); exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { computeComponentStackForErrorReporting: function (reactTag) {