|
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