@samitouri / QOS-React-2 / commits / 8ef14cf242

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