Skip to content

Commit 5b6d492

Browse files
committed
Batch async actions even if useTransition is unmounted (#28078)
If there are multiple updates inside an async action, they should all be rendered in the same batch, even if they are separate by an async operation (`await`). We currently implement this by suspending in the `useTransition` hook to block the update from committing until all possible updates have been scheduled by the action. The reason we did it this way is so you can "cancel" an action by navigating away from the UI that triggered it. The problem with that approach, though, is that even if you navigate away from the `useTransition` hook, the action may have updated shared parts of the UI that are still in the tree. So we may need to continue suspending even after the `useTransition` hook is deleted. In other words, the lifetime of an async action scope is longer than the lifetime of a particular `useTransition` hook. The solution is to suspend whenever _any_ update that is part of the async action scope is unwrapped during render. So, inside useState and useReducer. This fixes a related issue where an optimistic update is reverted before the async action has finished, because we were relying on the `useTransition` hook to prevent the optimistic update from finishing. This also prepares us to support async actions being passed to the non-hook form of `startTransition` (though this isn't implemented yet). DiffTrain build for commit 11c9fd0.
1 parent 95c2763 commit 5b6d492

13 files changed

+12952
-12771
lines changed

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js

+3,124-3,092
Large diffs are not rendered by default.

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js

+667-658
Large diffs are not rendered by default.

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js

+710-701
Large diffs are not rendered by default.

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ if (__DEV__) {
2424
) {
2525
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
2626
}
27-
var ReactVersion = "18.3.0-canary-2efb14260-20240124";
27+
var ReactVersion = "18.3.0-canary-11c9fd0c5-20240124";
2828

2929
// ATTENTION
3030
// When adding new symbols to this file,

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -539,4 +539,4 @@ exports.useSyncExternalStore = function (
539539
exports.useTransition = function () {
540540
return ReactCurrentDispatcher.current.useTransition();
541541
};
542-
exports.version = "18.3.0-canary-2efb14260-20240124";
542+
exports.version = "18.3.0-canary-11c9fd0c5-20240124";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ exports.useSyncExternalStore = function (
535535
exports.useTransition = function () {
536536
return ReactCurrentDispatcher.current.useTransition();
537537
};
538-
exports.version = "18.3.0-canary-2efb14260-20240124";
538+
exports.version = "18.3.0-canary-11c9fd0c5-20240124";
539539
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
540540
"function" ===
541541
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2efb1426067322cdb08304432b3ac849dee52bd9
1+
11c9fd0c53133f24f5270d36591b65b8fc2ebd25

0 commit comments

Comments
 (0)