Skip to content

Conversation

@xuanxuan321
Copy link

Summary

Fixes #30580

This PR fixes a bug where controlled <select> elements were being incorrectly reset after form submission when using form actions, while controlled <input> elements correctly maintained their values.

Problem

When a form with a controlled select element is submitted using a form action, React automatically calls form.reset() after the action completes. According to the HTML specification:

  • Input elements read from the value attribute (corresponding to defaultValue property)
  • Select elements read from option's selected attribute (corresponding to defaultSelected property)

React was syncing defaultValue for controlled inputs but not syncing defaultSelected for controlled selects. This caused selects to reset to an undefined state rather than maintaining their controlled value.

Solution

Modified three functions in ReactDOMSelect.js to sync the defaultSelected attribute for controlled select elements, making their behavior consistent with controlled inputs:

  1. initSelect() - line 155
  2. updateSelect() - line 224
  3. restoreControlledSelectState() - line 241

Changed the setDefaultSelected parameter from false to true when value != null (controlled component).

Test Plan

  • Added new test case: "controlled select elements maintain their value after form reset"
  • All 45 ReactDOMForm tests pass ✅
  • All 63 ReactDOMSelect tests pass ✅
  • No regressions in existing functionality

How to Test

function App() {
  const [type, setType] = useState("2");
  
  return (
    <form action={async () => { /* async action */ }}>
      <select value={type} onChange={(e) => setType(e.target.value)}>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
      </select>
    </form>
  );
}

Before fix: Select resets to first option after form submission
After fix: Select maintains the controlled value ✅

Fixes facebook#30580

When a form with a controlled select element is submitted using a form
action, React automatically calls form.reset() after the action completes.
This was causing controlled select elements to lose their values, while
controlled input elements correctly maintained their state.

The issue occurs because form.reset() reads from the DOM's default
attributes:
- For inputs: reads from the 'value' attribute (defaultValue property)
- For selects: reads from the 'selected' attribute (defaultSelected property)

React was syncing defaultValue for controlled inputs, but not syncing
defaultSelected for controlled selects. This caused selects to reset to
an undefined state rather than maintaining their controlled value.

This fix ensures that controlled select elements also sync their
defaultSelected attribute, making their behavior consistent with
controlled inputs.

Changes:
- Updated initSelect() to sync defaultSelected for controlled selects
- Updated updateSelect() to sync defaultSelected for controlled selects
- Updated restoreControlledSelectState() to sync defaultSelected
- Added test case verifying controlled select behavior after form reset

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
@meta-cla
Copy link

meta-cla bot commented Dec 30, 2025

Hi @xuanxuan321!

Thank you for your pull request and welcome to our community.

Action Required

In 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.

Process

In 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 CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at [email protected]. Thanks!

@meta-cla meta-cla bot added the CLA Signed label Dec 30, 2025
@meta-cla
Copy link

meta-cla bot commented Dec 30, 2025

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[React 19] Controlled <select> component is subject to automatic form reset

1 participant