-
Notifications
You must be signed in to change notification settings - Fork 50.2k
Fix: Forms should not reset when action fails #35354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Forms were incorrectly being reset even when form actions threw errors. This was because requestFormReset was called before the action executed. Now requestFormReset is only called if the action completes without throwing a synchronous error. For async actions, the form reset is scheduled immediately after the action is called (before it resolves), which is the correct behavior. Added test to verify forms remain dirty when actions fail. Fixes facebook#35295
|
Hi @rdanciu11! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at [email protected]. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
Good catch on this form behavior issue! 👍 Problem: Forms were being reset even when actions failed, which is unexpected UX - users lose their input data when errors occur. Your Solution: Wrap the action call in try-catch and only call However, there's a potential issue: The current implementation only handles synchronous errors. For async actions that reject (which is more common), the form will still reset because the promise rejection happens after the try-catch block completes. Suggested Fix: const result = action(formData);
// Check if result is a Promise
if (result && typeof result.then === 'function') {
return result.then(
(value) => {
requestFormReset(formFiber);
return value;
},
(error) => {
// Don't reset on async errors
throw error;
}
);
} else {
requestFormReset(formFiber);
return result;
}This handles both sync and async errors properly. Your test case uses Test Improvement: action={() => { throw new Error('Sync error'); }}Great work identifying this issue! Just needs a small adjustment for async error handling. 🚀 |
|
Thanks for the feedback. I've updated the implementation to properly handle both synchronous and asynchronous action failures. Note on implementation approach: Instead, I moved the async handling logic into
Changes include:
All existing tests pass, and the new tests ensure the form preserves user input when actions fail. This should fully address the UX issue where forms were being reset on failed actions. |
|
@eps1lon did you reference this PR by mistake? I don't think my change would affect anything in this area, so I think this should probably be reopened |
Forms were incorrectly being reset even when form actions threw errors. This was because requestFormReset was called before the action executed.
Now requestFormReset is only called if the action completes without throwing a synchronous error. For async actions, the form reset is scheduled immediately after the action is called (before it resolves), which is the correct behavior.
Added test to verify forms remain dirty when actions fail.
Fixes #35295
Summary
Fixes #35295
Forms were being reset even when form actions failed/threw errors. This was incorrect behavior according to the React documentation which states:
Root Cause
In
startHostTransition(line ~3270 inReactFiberHooks.js),requestFormReset(formFiber)was being called beforeaction(formData)executed, causing forms to reset regardless of whether the action succeeded or failed.Solution
Wrapped the action call in try/catch so that
requestFormResetis only called if the action doesn't throw a synchronous error. For async actions, the form reset is scheduled immediately after the action is called (before the promise resolves), which matches the existing behavior for successful async actions.How did you test this change?
Reproduced the bug using the CodeSandbox from issue Bug: Forms are reset when action fails #35295
Verified the fix
ReactDOMForm-test.jspassRan test commands: