Skip to content

Commit

Permalink
Async action support for React.startTransition (#28097)
Browse files Browse the repository at this point in the history
This adds support for async actions to the "isomorphic" version of
startTransition (i.e. the one exported by the "react" package).
Previously, async actions were only supported by the startTransition
that is returned from the useTransition hook.

The interesting part about the isomorphic startTransition is that it's
not associated with any particular root. It must work with updates to
arbitrary roots, or even arbitrary React renderers in the same app. (For
example, both React DOM and React Three Fiber.)

The idea is that React.startTransition should behave as if every root
had an implicit useTransition hook, and you composed together all the
startTransitions provided by those hooks. Multiple updates to the same
root will be batched together. However, updates to one root will not be
batched with updates to other roots.

Features like useOptimistic work the same as with the hook version.

There is one difference from from the hook version of startTransition:
an error triggered inside an async action cannot be captured by an error
boundary, because it's not associated with any particular part of the
tree. You should handle errors the same way you would in a regular
event, e.g. with a global error event handler, or with a local
`try/catch`.

DiffTrain build for [85b296e](85b296e)
  • Loading branch information
acdlite committed Jan 26, 2024
1 parent b9b97d9 commit bd16b96
Show file tree
Hide file tree
Showing 26 changed files with 1,300 additions and 762 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
382190c595126837ee7e43b4fa953f4edd30e01c
85b296e9b6ded4accd9ec3389297f95091fb1ac0
17 changes: 13 additions & 4 deletions compiled/facebook-www/React-dev.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ if (__DEV__) {
) {
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
}
var ReactVersion = "18.3.0-www-classic-92f5a9ab";
var ReactVersion = "18.3.0-www-classic-af9ffe5b";

// ATTENTION
// When adding new symbols to this file,
Expand Down Expand Up @@ -2961,8 +2961,14 @@ if (__DEV__) {
}

function startTransition(scope, options) {
var prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = {};
var prevTransition = ReactCurrentBatchConfig.transition; // Each renderer registers a callback to receive the return value of
// the scope function. This is used to implement async actions.

var callbacks = new Set();
var transition = {
_callbacks: callbacks
};
ReactCurrentBatchConfig.transition = transition;
var currentTransition = ReactCurrentBatchConfig.transition;

{
Expand All @@ -2979,7 +2985,10 @@ if (__DEV__) {
}

try {
scope();
var returnValue = scope();
callbacks.forEach(function (callback) {
return callback(currentTransition, returnValue);
});
} finally {
ReactCurrentBatchConfig.transition = prevTransition;

Expand Down
17 changes: 13 additions & 4 deletions compiled/facebook-www/React-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ if (__DEV__) {
) {
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
}
var ReactVersion = "18.3.0-www-modern-c131adbc";
var ReactVersion = "18.3.0-www-modern-c761065d";

// ATTENTION
// When adding new symbols to this file,
Expand Down Expand Up @@ -2926,8 +2926,14 @@ if (__DEV__) {
}

function startTransition(scope, options) {
var prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = {};
var prevTransition = ReactCurrentBatchConfig.transition; // Each renderer registers a callback to receive the return value of
// the scope function. This is used to implement async actions.

var callbacks = new Set();
var transition = {
_callbacks: callbacks
};
ReactCurrentBatchConfig.transition = transition;
var currentTransition = ReactCurrentBatchConfig.transition;

{
Expand All @@ -2944,7 +2950,10 @@ if (__DEV__) {
}

try {
scope();
var returnValue = scope();
callbacks.forEach(function (callback) {
return callback(currentTransition, returnValue);
});
} finally {
ReactCurrentBatchConfig.transition = prevTransition;

Expand Down
13 changes: 9 additions & 4 deletions compiled/facebook-www/React-prod.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,15 +444,20 @@ exports.memo = function (type, compare) {
};
};
exports.startTransition = function (scope, options) {
var prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = {};
var prevTransition = ReactCurrentBatchConfig.transition,
callbacks = new Set();
ReactCurrentBatchConfig.transition = { _callbacks: callbacks };
var currentTransition = ReactCurrentBatchConfig.transition;
enableTransitionTracing &&
void 0 !== options &&
void 0 !== options.name &&
((ReactCurrentBatchConfig.transition.name = options.name),
(ReactCurrentBatchConfig.transition.startTime = -1));
try {
scope();
var returnValue = scope();
callbacks.forEach(function (callback) {
return callback(currentTransition, returnValue);
});
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
Expand Down Expand Up @@ -546,4 +551,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-classic-63557ef1";
exports.version = "18.3.0-www-classic-d6e83430";
13 changes: 9 additions & 4 deletions compiled/facebook-www/React-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -437,15 +437,20 @@ exports.memo = function (type, compare) {
};
};
exports.startTransition = function (scope, options) {
var prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = {};
var prevTransition = ReactCurrentBatchConfig.transition,
callbacks = new Set();
ReactCurrentBatchConfig.transition = { _callbacks: callbacks };
var currentTransition = ReactCurrentBatchConfig.transition;
enableTransitionTracing &&
void 0 !== options &&
void 0 !== options.name &&
((ReactCurrentBatchConfig.transition.name = options.name),
(ReactCurrentBatchConfig.transition.startTime = -1));
try {
scope();
var returnValue = scope();
callbacks.forEach(function (callback) {
return callback(currentTransition, returnValue);
});
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
Expand Down Expand Up @@ -538,4 +543,4 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-modern-14d3332b";
exports.version = "18.3.0-www-modern-5a0946d0";
13 changes: 9 additions & 4 deletions compiled/facebook-www/React-profiling.classic.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,15 +448,20 @@ exports.memo = function (type, compare) {
};
};
exports.startTransition = function (scope, options) {
var prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = {};
var prevTransition = ReactCurrentBatchConfig.transition,
callbacks = new Set();
ReactCurrentBatchConfig.transition = { _callbacks: callbacks };
var currentTransition = ReactCurrentBatchConfig.transition;
enableTransitionTracing &&
void 0 !== options &&
void 0 !== options.name &&
((ReactCurrentBatchConfig.transition.name = options.name),
(ReactCurrentBatchConfig.transition.startTime = -1));
try {
scope();
var returnValue = scope();
callbacks.forEach(function (callback) {
return callback(currentTransition, returnValue);
});
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
Expand Down Expand Up @@ -550,7 +555,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-classic-de2439d8";
exports.version = "18.3.0-www-classic-00275770";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
13 changes: 9 additions & 4 deletions compiled/facebook-www/React-profiling.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -441,15 +441,20 @@ exports.memo = function (type, compare) {
};
};
exports.startTransition = function (scope, options) {
var prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = {};
var prevTransition = ReactCurrentBatchConfig.transition,
callbacks = new Set();
ReactCurrentBatchConfig.transition = { _callbacks: callbacks };
var currentTransition = ReactCurrentBatchConfig.transition;
enableTransitionTracing &&
void 0 !== options &&
void 0 !== options.name &&
((ReactCurrentBatchConfig.transition.name = options.name),
(ReactCurrentBatchConfig.transition.startTime = -1));
try {
scope();
var returnValue = scope();
callbacks.forEach(function (callback) {
return callback(currentTransition, returnValue);
});
} finally {
ReactCurrentBatchConfig.transition = prevTransition;
}
Expand Down Expand Up @@ -542,7 +547,7 @@ exports.useSyncExternalStore = function (
exports.useTransition = function () {
return ReactCurrentDispatcher.current.useTransition();
};
exports.version = "18.3.0-www-modern-5b70880a";
exports.version = "18.3.0-www-modern-a0181100";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
"function" ===
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
Expand Down
Loading

0 comments on commit bd16b96

Please sign in to comment.