|
7 | 7 | * @noflow
|
8 | 8 | * @nolint
|
9 | 9 | * @preventMunge
|
10 |
| - * @generated SignedSource<<cbd8ea0713685000d0b28083e1b0ef92>> |
| 10 | + * @generated SignedSource<<ae1a8bf6624e4c6f9e70730750430a22>> |
11 | 11 | */
|
12 | 12 |
|
13 | 13 | 'use strict';
|
@@ -8071,34 +8071,48 @@ function runFormStateAction(actionQueue, setState, payload) {
|
8071 | 8071 | }
|
8072 | 8072 |
|
8073 | 8073 | try {
|
8074 |
| - var promise = action(prevState, payload); |
| 8074 | + var returnValue = action(prevState, payload); |
8075 | 8075 |
|
8076 |
| - if (true) { |
8077 |
| - if ( |
8078 |
| - promise === null || |
8079 |
| - typeof promise !== "object" || |
8080 |
| - typeof promise.then !== "function" |
8081 |
| - ) { |
8082 |
| - error("The action passed to useFormState must be an async function."); |
8083 |
| - } |
8084 |
| - } // Attach a listener to read the return state of the action. As soon as this |
8085 |
| - // resolves, we can run the next action in the sequence. |
8086 |
| - |
8087 |
| - promise.then( |
8088 |
| - function (nextState) { |
8089 |
| - actionQueue.state = nextState; |
8090 |
| - finishRunningFormStateAction(actionQueue, setState); |
8091 |
| - }, |
8092 |
| - function () { |
8093 |
| - return finishRunningFormStateAction(actionQueue, setState); |
8094 |
| - } |
8095 |
| - ); // Create a thenable that resolves once the current async action scope has |
8096 |
| - // finished. Then stash that thenable in state. We'll unwrap it with the |
8097 |
| - // `use` algorithm during render. This is the same logic used |
8098 |
| - // by startTransition. |
| 8076 | + if ( |
| 8077 | + returnValue !== null && |
| 8078 | + typeof returnValue === "object" && // $FlowFixMe[method-unbinding] |
| 8079 | + typeof returnValue.then === "function" |
| 8080 | + ) { |
| 8081 | + var thenable = returnValue; // Attach a listener to read the return state of the action. As soon as |
| 8082 | + // this resolves, we can run the next action in the sequence. |
| 8083 | + |
| 8084 | + thenable.then( |
| 8085 | + function (nextState) { |
| 8086 | + actionQueue.state = nextState; |
| 8087 | + finishRunningFormStateAction(actionQueue, setState); |
| 8088 | + }, |
| 8089 | + function () { |
| 8090 | + return finishRunningFormStateAction(actionQueue, setState); |
| 8091 | + } |
| 8092 | + ); |
| 8093 | + var entangledResult = requestAsyncActionContext(thenable, null); |
| 8094 | + setState(entangledResult); |
| 8095 | + } else { |
| 8096 | + // This is either `returnValue` or a thenable that resolves to |
| 8097 | + // `returnValue`, depending on whether we're inside an async action scope. |
| 8098 | + var _entangledResult = requestSyncActionContext(returnValue, null); |
8099 | 8099 |
|
8100 |
| - var entangledThenable = requestAsyncActionContext(promise, null); |
8101 |
| - setState(entangledThenable); |
| 8100 | + setState(_entangledResult); |
| 8101 | + var nextState = returnValue; |
| 8102 | + actionQueue.state = nextState; |
| 8103 | + finishRunningFormStateAction(actionQueue, setState); |
| 8104 | + } |
| 8105 | + } catch (error) { |
| 8106 | + // This is a trick to get the `useFormState` hook to rethrow the error. |
| 8107 | + // When it unwraps the thenable with the `use` algorithm, the error |
| 8108 | + // will be thrown. |
| 8109 | + var rejectedThenable = { |
| 8110 | + then: function () {}, |
| 8111 | + status: "rejected", |
| 8112 | + reason: error // $FlowFixMe: Not sure why this doesn't work |
| 8113 | + }; |
| 8114 | + setState(rejectedThenable); |
| 8115 | + finishRunningFormStateAction(actionQueue, setState); |
8102 | 8116 | } finally {
|
8103 | 8117 | ReactCurrentBatchConfig$2.transition = prevTransition;
|
8104 | 8118 |
|
@@ -8147,22 +8161,18 @@ function formStateReducer(oldState, newState) {
|
8147 | 8161 |
|
8148 | 8162 | function mountFormState(action, initialStateProp, permalink) {
|
8149 | 8163 | var initialState = initialStateProp;
|
8150 |
| - |
8151 |
| - var initialStateThenable = { |
8152 |
| - status: "fulfilled", |
8153 |
| - value: initialState, |
8154 |
| - then: function () {} |
8155 |
| - }; // State hook. The state is stored in a thenable which is then unwrapped by |
8156 | 8164 | // the `use` algorithm during render.
|
8157 | 8165 |
|
8158 | 8166 | var stateHook = mountWorkInProgressHook();
|
8159 |
| - stateHook.memoizedState = stateHook.baseState = initialStateThenable; |
| 8167 | + stateHook.memoizedState = stateHook.baseState = initialState; // TODO: Typing this "correctly" results in recursion limit errors |
| 8168 | + // const stateQueue: UpdateQueue<S | Awaited<S>, S | Awaited<S>> = { |
| 8169 | + |
8160 | 8170 | var stateQueue = {
|
8161 | 8171 | pending: null,
|
8162 | 8172 | lanes: NoLanes,
|
8163 | 8173 | dispatch: null,
|
8164 | 8174 | lastRenderedReducer: formStateReducer,
|
8165 |
| - lastRenderedState: initialStateThenable |
| 8175 | + lastRenderedState: initialState |
8166 | 8176 | };
|
8167 | 8177 | stateHook.queue = stateQueue;
|
8168 | 8178 | var setState = dispatchSetState.bind(
|
@@ -8216,9 +8226,14 @@ function updateFormStateImpl(
|
8216 | 8226 | currentStateHook,
|
8217 | 8227 | formStateReducer
|
8218 | 8228 | ),
|
8219 |
| - thenable = _updateReducerImpl[0]; // This will suspend until the action finishes. |
8220 |
| - |
8221 |
| - var state = useThenable(thenable); |
| 8229 | + actionResult = _updateReducerImpl[0]; // This will suspend until the action finishes. |
| 8230 | + |
| 8231 | + var state = |
| 8232 | + typeof actionResult === "object" && |
| 8233 | + actionResult !== null && // $FlowFixMe[method-unbinding] |
| 8234 | + typeof actionResult.then === "function" |
| 8235 | + ? useThenable(actionResult) |
| 8236 | + : actionResult; |
8222 | 8237 | var actionQueueHook = updateWorkInProgressHook();
|
8223 | 8238 | var actionQueue = actionQueueHook.queue;
|
8224 | 8239 | var dispatch = actionQueue.dispatch; // Check if a new action was passed. If so, update it in an effect.
|
@@ -8258,8 +8273,7 @@ function rerenderFormState(action, initialState, permalink) {
|
8258 | 8273 | return updateFormStateImpl(stateHook, currentStateHook, action);
|
8259 | 8274 | } // This is a mount. No updates to process.
|
8260 | 8275 |
|
8261 |
| - var thenable = stateHook.memoizedState; |
8262 |
| - var state = useThenable(thenable); |
| 8276 | + var state = stateHook.memoizedState; |
8263 | 8277 | var actionQueueHook = updateWorkInProgressHook();
|
8264 | 8278 | var actionQueue = actionQueueHook.queue;
|
8265 | 8279 | var dispatch = actionQueue.dispatch; // This may have changed during the rerender.
|
@@ -8686,12 +8700,12 @@ function startTransition(
|
8686 | 8700 | // This is either `finishedState` or a thenable that resolves to
|
8687 | 8701 | // `finishedState`, depending on whether we're inside an async
|
8688 | 8702 | // action scope.
|
8689 |
| - var _entangledResult = requestSyncActionContext( |
| 8703 | + var _entangledResult2 = requestSyncActionContext( |
8690 | 8704 | returnValue,
|
8691 | 8705 | finishedState
|
8692 | 8706 | );
|
8693 | 8707 |
|
8694 |
| - dispatchSetState(fiber, queue, _entangledResult); |
| 8708 | + dispatchSetState(fiber, queue, _entangledResult2); |
8695 | 8709 | }
|
8696 | 8710 | }
|
8697 | 8711 | } catch (error) {
|
@@ -24887,7 +24901,7 @@ function createFiberRoot(
|
24887 | 24901 | return root;
|
24888 | 24902 | }
|
24889 | 24903 |
|
24890 |
| -var ReactVersion = "18.3.0-canary-08a39539f-20231031"; |
| 24904 | +var ReactVersion = "18.3.0-canary-77c4ac2ce-20231031"; |
24891 | 24905 |
|
24892 | 24906 | // Might add PROFILE later.
|
24893 | 24907 |
|
|
0 commit comments