Skip to content

Commit

Permalink
Fix: Use action implementation at time of dispatch (#29618)
Browse files Browse the repository at this point in the history
Fixes the behavior of actions that are queued by useActionState to use
the action function that was current at the time it was dispatched, not
at the time it eventually executes.

The conceptual model is that the action is immediately dispatched, as if
it were sent to a remote server/worker. It's the remote worker that
maintains the queue, not the client.

This is another property of actions makes them more like event handlers
than like reducers.

DiffTrain build for commit 1631227.
  • Loading branch information
acdlite committed May 28, 2024
1 parent 8dd5eda commit ca3d324
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<5d2de112982cec5eac69c9d1f8e71fe5>>
* @generated SignedSource<<b01346a616a954f7e5c6aa02b898719f>>
*/

'use strict';
Expand Down Expand Up @@ -8595,26 +8595,26 @@ function dispatchActionState(fiber, actionQueue, setPendingState, setState, payl
// it immediately.
var newLast = {
payload: payload,
action: actionQueue.action,
next: null // circular

};
newLast.next = actionQueue.pending = newLast;
runActionStateAction(actionQueue, setPendingState, setState, payload);
runActionStateAction(actionQueue, setPendingState, setState, newLast);
} else {
// There's already an action running. Add to the queue.
var first = last.next;
var _newLast = {
payload: payload,
action: actionQueue.action,
next: first
};
actionQueue.pending = last.next = _newLast;
}
}

function runActionStateAction(actionQueue, setPendingState, setState, payload) {
var action = actionQueue.action;
var prevState = actionQueue.state; // This is a fork of startTransition

function runActionStateAction(actionQueue, setPendingState, setState, node) {
// This is a fork of startTransition
var prevTransition = ReactSharedInternals.T;
var currentTransition = {};
ReactSharedInternals.T = currentTransition;
Expand All @@ -8625,7 +8625,16 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) {
// This will be reverted automatically when all actions are finished.


setPendingState(true);
setPendingState(true); // `node.action` represents the action function at the time it was dispatched.
// If this action was queued, it might be stale, i.e. it's not necessarily the
// most current implementation of the action, stored on `actionQueue`. This is
// intentional. The conceptual model for queued actions is that they are
// queued in a remote worker; the dispatch happens immediately, only the
// execution is delayed.

var action = node.action;
var payload = node.payload;
var prevState = actionQueue.state;

try {
var returnValue = action(prevState, payload);
Expand Down Expand Up @@ -8698,7 +8707,7 @@ function finishRunningActionStateAction(actionQueue, setPendingState, setState)
var next = first.next;
last.next = next; // Run the next action.

runActionStateAction(actionQueue, setPendingState, setState, next.payload);
runActionStateAction(actionQueue, setPendingState, setState, next);
}
}
}
Expand Down Expand Up @@ -23462,7 +23471,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
return root;
}

var ReactVersion = '19.0.0-rc-44b67cc6';
var ReactVersion = '19.0.0-rc-0d4b9126';

/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<c50a413ebb22fd09d88e5c0cbdee55c9>>
* @generated SignedSource<<b82ab7c9a033e33f8860c7aed3aa5cae>>
*/

"use strict";
Expand Down Expand Up @@ -2773,21 +2773,22 @@ function dispatchActionState(
throw Error("Cannot update form state while rendering.");
fiber = actionQueue.pending;
null === fiber
? ((fiber = { payload: payload, next: null }),
(fiber.next = actionQueue.pending = fiber),
? ((payload = { payload: payload, action: actionQueue.action, next: null }),
(payload.next = actionQueue.pending = payload),
runActionStateAction(actionQueue, setPendingState, setState, payload))
: (actionQueue.pending = fiber.next =
{ payload: payload, next: fiber.next });
{ payload: payload, action: actionQueue.action, next: fiber.next });
}
function runActionStateAction(actionQueue, setPendingState, setState, payload) {
var action = actionQueue.action,
prevState = actionQueue.state,
prevTransition = ReactSharedInternals.T,
function runActionStateAction(actionQueue, setPendingState, setState, node) {
var prevTransition = ReactSharedInternals.T,
currentTransition = {};
ReactSharedInternals.T = currentTransition;
setPendingState(!0);
var action = node.action;
node = node.payload;
var prevState = actionQueue.state;
try {
var returnValue = action(prevState, payload),
var returnValue = action(prevState, node),
onStartTransitionFinish = ReactSharedInternals.S;
null !== onStartTransitionFinish &&
onStartTransitionFinish(currentTransition, returnValue);
Expand Down Expand Up @@ -2834,12 +2835,7 @@ function finishRunningActionStateAction(
? (actionQueue.pending = null)
: ((first = first.next),
(last.next = first),
runActionStateAction(
actionQueue,
setPendingState,
setState,
first.payload
));
runActionStateAction(actionQueue, setPendingState, setState, first));
}
}
function actionStateReducer(oldState, newState) {
Expand Down Expand Up @@ -9302,7 +9298,7 @@ var devToolsConfig$jscomp$inline_1047 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "19.0.0-rc-96bb2a1a",
version: "19.0.0-rc-135fcf29",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1234 = {
Expand Down Expand Up @@ -9333,7 +9329,7 @@ var internals$jscomp$inline_1234 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-rc-96bb2a1a"
reconcilerVersion: "19.0.0-rc-135fcf29"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1235 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<382b340fe45aa68c7ed8c70111650a72>>
* @generated SignedSource<<b303e864c1beaa1151f860061b09a0be>>
*/

"use strict";
Expand Down Expand Up @@ -2861,21 +2861,22 @@ function dispatchActionState(
throw Error("Cannot update form state while rendering.");
fiber = actionQueue.pending;
null === fiber
? ((fiber = { payload: payload, next: null }),
(fiber.next = actionQueue.pending = fiber),
? ((payload = { payload: payload, action: actionQueue.action, next: null }),
(payload.next = actionQueue.pending = payload),
runActionStateAction(actionQueue, setPendingState, setState, payload))
: (actionQueue.pending = fiber.next =
{ payload: payload, next: fiber.next });
{ payload: payload, action: actionQueue.action, next: fiber.next });
}
function runActionStateAction(actionQueue, setPendingState, setState, payload) {
var action = actionQueue.action,
prevState = actionQueue.state,
prevTransition = ReactSharedInternals.T,
function runActionStateAction(actionQueue, setPendingState, setState, node) {
var prevTransition = ReactSharedInternals.T,
currentTransition = {};
ReactSharedInternals.T = currentTransition;
setPendingState(!0);
var action = node.action;
node = node.payload;
var prevState = actionQueue.state;
try {
var returnValue = action(prevState, payload),
var returnValue = action(prevState, node),
onStartTransitionFinish = ReactSharedInternals.S;
null !== onStartTransitionFinish &&
onStartTransitionFinish(currentTransition, returnValue);
Expand Down Expand Up @@ -2922,12 +2923,7 @@ function finishRunningActionStateAction(
? (actionQueue.pending = null)
: ((first = first.next),
(last.next = first),
runActionStateAction(
actionQueue,
setPendingState,
setState,
first.payload
));
runActionStateAction(actionQueue, setPendingState, setState, first));
}
}
function actionStateReducer(oldState, newState) {
Expand Down Expand Up @@ -9924,7 +9920,7 @@ var devToolsConfig$jscomp$inline_1130 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "19.0.0-rc-d4795057",
version: "19.0.0-rc-17313e5b",
rendererPackageName: "react-test-renderer"
};
(function (internals) {
Expand Down Expand Up @@ -9968,7 +9964,7 @@ var devToolsConfig$jscomp$inline_1130 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-rc-d4795057"
reconcilerVersion: "19.0.0-rc-17313e5b"
});
exports._Scheduler = Scheduler;
exports.act = act;
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2787eebe52864356252a280fd811cd9d52807a82
163122766b6008e992898b00f1fe3b104ed78737
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<d66dfe0f482a855f5a25c6611f697b38>>
* @generated SignedSource<<e788833561fd15923c3878d11f308805>>
*/

'use strict';
Expand Down Expand Up @@ -11341,26 +11341,26 @@ function dispatchActionState(fiber, actionQueue, setPendingState, setState, payl
// it immediately.
var newLast = {
payload: payload,
action: actionQueue.action,
next: null // circular

};
newLast.next = actionQueue.pending = newLast;
runActionStateAction(actionQueue, setPendingState, setState, payload);
runActionStateAction(actionQueue, setPendingState, setState, newLast);
} else {
// There's already an action running. Add to the queue.
var first = last.next;
var _newLast = {
payload: payload,
action: actionQueue.action,
next: first
};
actionQueue.pending = last.next = _newLast;
}
}

function runActionStateAction(actionQueue, setPendingState, setState, payload) {
var action = actionQueue.action;
var prevState = actionQueue.state; // This is a fork of startTransition

function runActionStateAction(actionQueue, setPendingState, setState, node) {
// This is a fork of startTransition
var prevTransition = ReactSharedInternals.T;
var currentTransition = {};
ReactSharedInternals.T = currentTransition;
Expand All @@ -11371,7 +11371,16 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) {
// This will be reverted automatically when all actions are finished.


setPendingState(true);
setPendingState(true); // `node.action` represents the action function at the time it was dispatched.
// If this action was queued, it might be stale, i.e. it's not necessarily the
// most current implementation of the action, stored on `actionQueue`. This is
// intentional. The conceptual model for queued actions is that they are
// queued in a remote worker; the dispatch happens immediately, only the
// execution is delayed.

var action = node.action;
var payload = node.payload;
var prevState = actionQueue.state;

try {
var returnValue = action(prevState, payload);
Expand Down Expand Up @@ -11444,7 +11453,7 @@ function finishRunningActionStateAction(actionQueue, setPendingState, setState)
var next = first.next;
last.next = next; // Run the next action.

runActionStateAction(actionQueue, setPendingState, setState, next.payload);
runActionStateAction(actionQueue, setPendingState, setState, next);
}
}
}
Expand Down Expand Up @@ -26203,7 +26212,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition
return root;
}

var ReactVersion = '19.0.0-rc-571af8c1';
var ReactVersion = '19.0.0-rc-e4976d97';

/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<2010209dd2101a00236bbe4927c1ce22>>
* @generated SignedSource<<90fa919b6a227b2cc430690a633373b6>>
*/

"use strict";
Expand Down Expand Up @@ -4153,21 +4153,22 @@ function dispatchActionState(
throw Error("Cannot update form state while rendering.");
fiber = actionQueue.pending;
null === fiber
? ((fiber = { payload: payload, next: null }),
(fiber.next = actionQueue.pending = fiber),
? ((payload = { payload: payload, action: actionQueue.action, next: null }),
(payload.next = actionQueue.pending = payload),
runActionStateAction(actionQueue, setPendingState, setState, payload))
: (actionQueue.pending = fiber.next =
{ payload: payload, next: fiber.next });
{ payload: payload, action: actionQueue.action, next: fiber.next });
}
function runActionStateAction(actionQueue, setPendingState, setState, payload) {
var action = actionQueue.action,
prevState = actionQueue.state,
prevTransition = ReactSharedInternals.T,
function runActionStateAction(actionQueue, setPendingState, setState, node) {
var prevTransition = ReactSharedInternals.T,
currentTransition = {};
ReactSharedInternals.T = currentTransition;
setPendingState(!0);
var action = node.action;
node = node.payload;
var prevState = actionQueue.state;
try {
var returnValue = action(prevState, payload),
var returnValue = action(prevState, node),
onStartTransitionFinish = ReactSharedInternals.S;
null !== onStartTransitionFinish &&
onStartTransitionFinish(currentTransition, returnValue);
Expand Down Expand Up @@ -4214,12 +4215,7 @@ function finishRunningActionStateAction(
? (actionQueue.pending = null)
: ((first = first.next),
(last.next = first),
runActionStateAction(
actionQueue,
setPendingState,
setState,
first.payload
));
runActionStateAction(actionQueue, setPendingState, setState, first));
}
}
function actionStateReducer(oldState, newState) {
Expand Down Expand Up @@ -10558,7 +10554,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1124 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "19.0.0-rc-68b4213e",
version: "19.0.0-rc-515f4c11",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForInstance: getInspectorDataForInstance,
Expand Down Expand Up @@ -10601,7 +10597,7 @@ var internals$jscomp$inline_1354 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-rc-68b4213e"
reconcilerVersion: "19.0.0-rc-515f4c11"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1355 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Loading

0 comments on commit ca3d324

Please sign in to comment.