Skip to content

Commit

Permalink
Bugfix: useFormState queues actions in wrong order (#27570)
Browse files Browse the repository at this point in the history
I neglected to update the "last" pointer of the action queue. Since the
queue is circular, rather than dropping the update, the effect was to
add the update to the front of the queue instead of the back. I didn't
notice earlier because in my demos/tests, the actions would either
resolve really quickly or the actions weren't order dependent (like
incrementing a counter).
  • Loading branch information
acdlite authored Oct 23, 2023
1 parent 05fbd1a commit b8e47d9
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
31 changes: 30 additions & 1 deletion packages/react-dom/src/__tests__/ReactDOMForm-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe('ReactDOMForm', () => {
const thenable = record.value;
record.status = 'resolved';
record.value = text;
thenable.pings.forEach(t => t());
thenable.pings.forEach(t => t(text));
}
}

Expand Down Expand Up @@ -1082,6 +1082,35 @@ describe('ReactDOMForm', () => {
});
});

// @gate enableFormActions
// @gate enableAsyncActions
test('queues multiple actions and runs them in order', async () => {
let action;
function App() {
const [state, dispatch] = useFormState(
async (s, a) => await getText(a),
'A',
);
action = dispatch;
return <Text text={state} />;
}

const root = ReactDOMClient.createRoot(container);
await act(() => root.render(<App />));
assertLog(['A']);

await act(() => action('B'));
await act(() => action('C'));
await act(() => action('D'));

await act(() => resolveText('B'));
await act(() => resolveText('C'));
await act(() => resolveText('D'));

assertLog(['D']);
expect(container.textContent).toBe('D');
});

// @gate enableFormActions
// @gate enableAsyncActions
test('useFormState: warns if action is not async', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-reconciler/src/ReactFiberHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -1915,7 +1915,7 @@ function dispatchFormState<S, P>(
payload,
next: first,
};
last.next = newLast;
actionQueue.pending = last.next = newLast;
}
}

Expand Down

0 comments on commit b8e47d9

Please sign in to comment.