From 77b37d313921a4eae4f6c39620a2911ef0798372 Mon Sep 17 00:00:00 2001 From: hassanzadeh Date: Thu, 23 Apr 2026 21:54:31 +0330 Subject: [PATCH] Add autoReset prop to opt out of automatic form reset on actions (#29034) React 19 automatically calls form.reset() after every form action. This adds an `autoReset` prop (default: true) to let users opt out by passing `autoReset={false}` on the form element. Co-Authored-By: Claude Sonnet 4.6 --- .../src/events/plugins/FormActionEventPlugin.js | 13 ++++++++----- packages/react-reconciler/src/ReactFiberHooks.js | 7 +++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js b/packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js index 420d1d118820..c0fcd2f3da4b 100644 --- a/packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js +++ b/packages/react-dom-bindings/src/events/plugins/FormActionEventPlugin.js @@ -68,9 +68,9 @@ function extractEvents( } const formInst = maybeTargetInst; const form: HTMLFormElement = (nativeEventTarget: any); - let action = coerceFormActionProp( - (getFiberCurrentPropsFromNode(form): any).action, - ); + const formProps = (getFiberCurrentPropsFromNode(form): any); + let action = coerceFormActionProp(formProps.action); + const autoReset: boolean = formProps.autoReset !== false; let submitter: null | void | HTMLInputElement | HTMLButtonElement = (nativeEvent: any).submitter; let submitterAction; @@ -124,6 +124,7 @@ function extractEvents( // the action. null, formData, + autoReset, ); } else { // No earlier event scheduled a transition. Exit without setting a @@ -144,7 +145,7 @@ function extractEvents( if (__DEV__) { Object.freeze(pendingState); } - startHostTransition(formInst, pendingState, action, formData); + startHostTransition(formInst, pendingState, action, formData, autoReset); } else { // No earlier event prevented the default submission, and no action was // provided. Exit without setting a pending form status. @@ -180,5 +181,7 @@ export function dispatchReplayedFormAction( if (__DEV__) { Object.freeze(pendingState); } - startHostTransition(formInst, pendingState, action, formData); + const autoReset: boolean = + (getFiberCurrentPropsFromNode(form): any).autoReset !== false; + startHostTransition(formInst, pendingState, action, formData, autoReset); } diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index 29c83c7d7263..0df0ad865a28 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -3240,6 +3240,7 @@ export function startHostTransition( pendingState: TransitionStatus, action: (F => mixed) | null, formData: F, + autoReset: boolean = true, ): void { if (formFiber.tag !== HostComponent) { throw new Error( @@ -3271,8 +3272,10 @@ export function startHostTransition( // set the pending form status. noop : () => { - // Automatically reset the form when the action completes. - requestFormReset(formFiber); + if (autoReset) { + // Automatically reset the form when the action completes. + requestFormReset(formFiber); + } return action(formData); }, );