Skip to content

Commit 8e12d48

Browse files
committed
Add pending state to useFormState (#28514)
## Overview Adds a `pending` state to useFormState, which will be replaced by `useActionState` in the next diff. We will keep `useFormState` around for backwards compatibility, but functionally it will work the same as `useActionState`, which has an `isPending` state returned. DiffTrain build for [17eaaca](17eaaca)
1 parent 43ce284 commit 8e12d48

27 files changed

+966
-371
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3e6bc7d2d7098d9c8a30ba6e7a877df70f4d8d34
1+
17eaacaac167addf0c4358b4983f054073a0626d

compiled/facebook-www/React-prod.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,4 +633,4 @@ exports.useSyncExternalStore = function (
633633
exports.useTransition = function () {
634634
return ReactCurrentDispatcher.current.useTransition();
635635
};
636-
exports.version = "18.3.0-www-classic-43ac25ba";
636+
exports.version = "18.3.0-www-classic-7c2abefb";

compiled/facebook-www/React-prod.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,4 +625,4 @@ exports.useSyncExternalStore = function (
625625
exports.useTransition = function () {
626626
return ReactCurrentDispatcher.current.useTransition();
627627
};
628-
exports.version = "18.3.0-www-modern-a7ff7332";
628+
exports.version = "18.3.0-www-modern-0337b6c3";

compiled/facebook-www/React-profiling.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ exports.useSyncExternalStore = function (
637637
exports.useTransition = function () {
638638
return ReactCurrentDispatcher.current.useTransition();
639639
};
640-
exports.version = "18.3.0-www-classic-ba07b7d4";
640+
exports.version = "18.3.0-www-classic-9048e373";
641641
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
642642
"function" ===
643643
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-profiling.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ exports.useSyncExternalStore = function (
629629
exports.useTransition = function () {
630630
return ReactCurrentDispatcher.current.useTransition();
631631
};
632-
exports.version = "18.3.0-www-modern-dc34ad0a";
632+
exports.version = "18.3.0-www-modern-c75eccb5";
633633
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
634634
"function" ===
635635
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/ReactART-dev.classic.js

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ if (__DEV__) {
6666
return self;
6767
}
6868

69-
var ReactVersion = "18.3.0-www-classic-3c471167";
69+
var ReactVersion = "18.3.0-www-classic-1172eaef";
7070

7171
var LegacyRoot = 0;
7272
var ConcurrentRoot = 1;
@@ -9873,7 +9873,13 @@ if (__DEV__) {
98739873
} // useFormState actions run sequentially, because each action receives the
98749874
// previous state as an argument. We store pending actions on a queue.
98759875

9876-
function dispatchFormState(fiber, actionQueue, setState, payload) {
9876+
function dispatchFormState(
9877+
fiber,
9878+
actionQueue,
9879+
setPendingState,
9880+
setState,
9881+
payload
9882+
) {
98779883
if (isRenderPhaseUpdate(fiber)) {
98789884
throw new Error("Cannot update form state while rendering.");
98799885
}
@@ -9888,7 +9894,7 @@ if (__DEV__) {
98889894
next: null // circular
98899895
};
98909896
newLast.next = actionQueue.pending = newLast;
9891-
runFormStateAction(actionQueue, setState, payload);
9897+
runFormStateAction(actionQueue, setPendingState, setState, payload);
98929898
} else {
98939899
// There's already an action running. Add to the queue.
98949900
var first = last.next;
@@ -9900,7 +9906,12 @@ if (__DEV__) {
99009906
}
99019907
}
99029908

9903-
function runFormStateAction(actionQueue, setState, payload) {
9909+
function runFormStateAction(
9910+
actionQueue,
9911+
setPendingState,
9912+
setState,
9913+
payload
9914+
) {
99049915
var action = actionQueue.action;
99059916
var prevState = actionQueue.state; // This is a fork of startTransition
99069917

@@ -9912,7 +9923,10 @@ if (__DEV__) {
99129923

99139924
{
99149925
ReactCurrentBatchConfig$2.transition._updatedFibers = new Set();
9915-
}
9926+
} // Optimistically update the pending state, similar to useTransition.
9927+
// This will be reverted automatically when all actions are finished.
9928+
9929+
setPendingState(true);
99169930

99179931
try {
99189932
var returnValue = action(prevState, payload);
@@ -9929,18 +9943,26 @@ if (__DEV__) {
99299943
thenable.then(
99309944
function (nextState) {
99319945
actionQueue.state = nextState;
9932-
finishRunningFormStateAction(actionQueue, setState);
9946+
finishRunningFormStateAction(
9947+
actionQueue,
9948+
setPendingState,
9949+
setState
9950+
);
99339951
},
99349952
function () {
9935-
return finishRunningFormStateAction(actionQueue, setState);
9953+
return finishRunningFormStateAction(
9954+
actionQueue,
9955+
setPendingState,
9956+
setState
9957+
);
99369958
}
99379959
);
99389960
setState(thenable);
99399961
} else {
99409962
setState(returnValue);
99419963
var nextState = returnValue;
99429964
actionQueue.state = nextState;
9943-
finishRunningFormStateAction(actionQueue, setState);
9965+
finishRunningFormStateAction(actionQueue, setPendingState, setState);
99449966
}
99459967
} catch (error) {
99469968
// This is a trick to get the `useFormState` hook to rethrow the error.
@@ -9952,7 +9974,7 @@ if (__DEV__) {
99529974
reason: error // $FlowFixMe: Not sure why this doesn't work
99539975
};
99549976
setState(rejectedThenable);
9955-
finishRunningFormStateAction(actionQueue, setState);
9977+
finishRunningFormStateAction(actionQueue, setPendingState, setState);
99569978
} finally {
99579979
ReactCurrentBatchConfig$2.transition = prevTransition;
99589980

@@ -9974,7 +9996,11 @@ if (__DEV__) {
99749996
}
99759997
}
99769998

9977-
function finishRunningFormStateAction(actionQueue, setState) {
9999+
function finishRunningFormStateAction(
10000+
actionQueue,
10001+
setPendingState,
10002+
setState
10003+
) {
997810004
// The action finished running. Pop it from the queue and run the next pending
997910005
// action, if there are any.
998010006
var last = actionQueue.pending;
@@ -9990,7 +10016,12 @@ if (__DEV__) {
999010016
var next = first.next;
999110017
last.next = next; // Run the next action.
999210018

9993-
runFormStateAction(actionQueue, setState, next.payload);
10019+
runFormStateAction(
10020+
actionQueue,
10021+
setPendingState,
10022+
setState,
10023+
next.payload
10024+
);
999410025
}
999510026
}
999610027
}
@@ -10020,7 +10051,16 @@ if (__DEV__) {
1002010051
currentlyRenderingFiber$1,
1002110052
stateQueue
1002210053
);
10023-
stateQueue.dispatch = setState; // Action queue hook. This is used to queue pending actions. The queue is
10054+
stateQueue.dispatch = setState; // Pending state. This is used to store the pending state of the action.
10055+
// Tracked optimistically, like a transition pending state.
10056+
10057+
var pendingStateHook = mountStateImpl(false);
10058+
var setPendingState = dispatchOptimisticSetState.bind(
10059+
null,
10060+
currentlyRenderingFiber$1,
10061+
false,
10062+
pendingStateHook.queue
10063+
); // Action queue hook. This is used to queue pending actions. The queue is
1002410064
// shared between all instances of the hook. Similar to a regular state queue,
1002510065
// but different because the actions are run sequentially, and they run in
1002610066
// an event instead of during render.
@@ -10038,14 +10078,15 @@ if (__DEV__) {
1003810078
null,
1003910079
currentlyRenderingFiber$1,
1004010080
actionQueue,
10081+
setPendingState,
1004110082
setState
1004210083
);
1004310084
actionQueue.dispatch = dispatch; // Stash the action function on the memoized state of the hook. We'll use this
1004410085
// to detect when the action function changes so we can update it in
1004510086
// an effect.
1004610087

1004710088
actionQueueHook.memoizedState = action;
10048-
return [initialState, dispatch];
10089+
return [initialState, dispatch, false];
1004910090
}
1005010091

1005110092
function updateFormState(action, initialState, permalink) {
@@ -10066,7 +10107,10 @@ if (__DEV__) {
1006610107
currentStateHook,
1006710108
formStateReducer
1006810109
),
10069-
actionResult = _updateReducerImpl[0]; // This will suspend until the action finishes.
10110+
actionResult = _updateReducerImpl[0];
10111+
10112+
var _updateState = updateState(),
10113+
isPending = _updateState[0]; // This will suspend until the action finishes.
1007010114

1007110115
var state =
1007210116
typeof actionResult === "object" &&
@@ -10090,7 +10134,7 @@ if (__DEV__) {
1009010134
);
1009110135
}
1009210136

10093-
return [state, dispatch];
10137+
return [state, dispatch, isPending];
1009410138
}
1009510139

1009610140
function formStateActionEffect(actionQueue, action) {
@@ -10118,8 +10162,9 @@ if (__DEV__) {
1011810162
var actionQueue = actionQueueHook.queue;
1011910163
var dispatch = actionQueue.dispatch; // This may have changed during the rerender.
1012010164

10121-
actionQueueHook.memoizedState = action;
10122-
return [state, dispatch];
10165+
actionQueueHook.memoizedState = action; // For mount, pending is always false.
10166+
10167+
return [state, dispatch, false];
1012310168
}
1012410169

1012510170
function pushEffect(tag, create, inst, deps) {
@@ -10758,8 +10803,8 @@ if (__DEV__) {
1075810803
}
1075910804

1076010805
function updateTransition() {
10761-
var _updateState = updateState(),
10762-
booleanOrThenable = _updateState[0];
10806+
var _updateState2 = updateState(),
10807+
booleanOrThenable = _updateState2[0];
1076310808

1076410809
var hook = updateWorkInProgressHook();
1076510810
var start = hook.memoizedState;

0 commit comments

Comments
 (0)