Ensure dispatch from `useFormState` works in `StrictMode` (#28557)
Co-authored-by: Andrew Clark <git@andrewclark.io>
Sebastian Silbermann committed
Mar 20, 2024 at 16:15 UTC
8ef14cf24219addedca3607dabb3bef37fb2e013
2 files changed
+50
packages/react-dom/src/__tests__/ReactDOMForm-test.js
+48
@@ -1295,4 +1295,52 @@ describe('ReactDOMForm', () => {
1295
assertLog(['B']);
1296
expect(container.textContent).toBe('B');
1297
});
1298
+
1299
+ // @gate enableFormActions
1300
+ // @gate enableAsyncActions
1301
+ test('useFormState works in StrictMode', async () => {
1302
+ let actionCounter = 0;
1303
+ async function action(state, type) {
1304
+ actionCounter++;
1305
+
1306
+ Scheduler.log(`Async action started [${actionCounter}]`);
1307
+ await getText(`Wait [${actionCounter}]`);
1308
+
1309
+ switch (type) {
1310
+ case 'increment':
1311
+ return state + 1;
1312
+ case 'decrement':
1313
+ return state - 1;
1314
+ default:
1315
+ return state;
1316
+ }
1317
+ }
1318
+
1319
+ let dispatch;
1320
+ function App() {
1321
+ const [state, _dispatch, isPending] = useFormState(action, 0);
1322
+ dispatch = _dispatch;
1323
+ const pending = isPending ? 'Pending ' : '';
1324
+ return <Text text={pending + state} />;
1325
+ }
1326
+
1327
+ const root = ReactDOMClient.createRoot(container);
1328
+ await act(() =>
1329
+ root.render(
1330
+ <React.StrictMode>
1331
+ <App />
1332
+ </React.StrictMode>,
1333
+ ),
1334
+ );
1335
+ assertLog(['0']);
1336
+ expect(container.textContent).toBe('0');
1337
+
1338
+ await act(() => dispatch('increment'));
1339
+ assertLog(['Async action started [1]', 'Pending 0']);
1340
+ expect(container.textContent).toBe('Pending 0');
1341
+
1342
+ await act(() => resolveText('Wait [1]'));
1343
+ assertLog(['1']);
1344
+ expect(container.textContent).toBe('1');
1345
+ });
1346
});
packages/react-reconciler/src/ReactFiberHooks.js
+2
@@ -2259,6 +2259,8 @@ function rerenderFormState<S, P>(
2259
);
2260
}
2261
2262
+ updateWorkInProgressHook(); // State
2263
+
2264
// This is a mount. No updates to process.
2265
const state: Awaited<S> = stateHook.memoizedState;
2266