You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
useActionState: Transfer transition context (#29694)
Mini-refactor of useActionState to only wrap the action in a transition
context if the dispatch is called during a transition. Conceptually, the
action starts as soon as the dispatch is called, even if the action is
queued until earlier ones finish.
We will also warn if an async action is dispatched outside of a
transition, since that is almost certainly a mistake. Ideally we would
automatically upgrade these to a transition, but we don't have a great
way to tell if the action is async until after it's already run.
DiffTrain build for [67b05be](67b05be)
if (prevTransition === null && currentTransition._updatedFibers) {
9366
-
var updatedFibersCount = currentTransition._updatedFibers.size;
9362
+
{
9363
+
if (prevTransition === null && currentTransition._updatedFibers) {
9364
+
var updatedFibersCount = currentTransition._updatedFibers.size;
9367
9365
9368
-
currentTransition._updatedFibers.clear();
9366
+
currentTransition._updatedFibers.clear();
9369
9367
9370
-
if (updatedFibersCount > 10) {
9371
-
warn('Detected a large number of updates inside startTransition. ' + 'If this is due to a subscription please re-write it to use React provided hooks. ' + 'Otherwise concurrent mode guarantees are off the table.');
9368
+
if (updatedFibersCount > 10) {
9369
+
warn('Detected a large number of updates inside startTransition. ' + 'If this is due to a subscription please re-write it to use React provided hooks. ' + 'Otherwise concurrent mode guarantees are off the table.');
9370
+
}
9372
9371
}
9373
9372
}
9374
9373
}
9374
+
} else {
9375
+
// The original dispatch was not part of a transition.
var thenable = returnValue; // Attach a listener to read the return state of the action. As soon as
9390
+
// this resolves, we can run the next action in the sequence.
9391
+
9392
+
thenable.then(function (nextState) {
9393
+
onActionSuccess(actionQueue, node, nextState);
9394
+
}, function (error) {
9395
+
return onActionError(actionQueue, node, error);
9396
+
});
9397
+
9398
+
{
9399
+
if (!node.isTransition) {
9400
+
error('An async function was passed to useActionState, but it was ' + 'dispatched outside of an action context. This is likely not ' + 'what you intended. Either pass the dispatch function to an ' + '`action` prop, or dispatch manually inside `startTransition`');
9401
+
}
9402
+
}
9403
+
} else {
9404
+
var nextState = returnValue;
9405
+
onActionSuccess(actionQueue, node, nextState);
9375
9406
}
9376
9407
}
9377
9408
9378
-
function finishRunningActionStateAction(actionQueue, setPendingState, setState) {
9379
-
// The action finished running. Pop it from the queue and run the next pending
9380
-
// action, if there are any.
9409
+
function onActionSuccess(actionQueue, actionNode, nextState) {
9410
+
// The action finished running.
9411
+
actionNode.status = 'fulfilled';
9412
+
actionNode.value = nextState;
9413
+
notifyActionListeners(actionNode);
9414
+
actionQueue.state = nextState; // Pop the action from the queue and run the next pending action, if there
9415
+
// are any.
9416
+
9381
9417
var last = actionQueue.pending;
9382
9418
9383
9419
if (last !== null) {
@@ -9391,11 +9427,48 @@ function finishRunningActionStateAction(actionQueue, setPendingState, setState)
0 commit comments