<Form action={myServerAction}> (or <form> with formAction={…}) and the action prop is a Server Action, Next.js intercepts the native form submission.fetch call to invoke your server function, then re-renders the current route via client-side navigation.<aside>
What actually happens after the fetch call is router.refresh() (automatic in App Router).
This re-executes the Server Components for the current route segment and streams the new HTML, but it is not a real browser navigation or a “hard reload.” It feels like a full re-render because every Server Component in that segment mounts again, but the client-side JS state outside the refreshed subtree survives. </aside>
This full-page re-render resets all uncontrolled inputs to their initial values (i.e. “clears” the form).
value via useState.form.reset() in React 19form.reset() after a successful Server Action (or when using useActionState), mimicking full-page navigation.selectedIndex, checked) to their default values before React’s next commit, causing a mismatch.<aside>
form.reset() only when the <form> specifies an action attribute (string URL or function reference / server action) or when you use useActionState / useFormState.<form onSubmit={…}> without an action attribute does not get auto-reset.
</aside>reset() mutates the DOM directly. React hasn’t yet reconciled, so if it believes a controlled prop hasn’t changed, it won’t overwrite the reset DOM.value on every commit, so even if reset() clears them, React immediately restores your controlled value.<select> / <input type="checkbox">: Due to Bug #30580, controlled props are only re-written on mount or when the prop itself changes. An external reset() isn’t regarded as a prop change, so their values stay cleared.<aside>
Note that the team marked it “accepted” and it should be fixed before React 19 final—but today (React 19 RC) it still happens.
</aside>