How to Set a Default Value in React Select: Uncontrolled vs Controlled Components

Use the defaultValue prop on an uncontrolled <select> element to set the initial selected option, or use the value prop with an onChange handler for a controlled component where React manages the state.

Setting a default value in a React select element is a fundamental pattern when building forms with the facebook/react repository. Whether you are rendering a simple dropdown or a complex multi-select interface, understanding how React handles the defaultValue prop versus the controlled value prop ensures predictable form behavior and avoids common runtime warnings.

Understanding the defaultValue Prop in React

React treats a <select> element like other form controls: you can render it uncontrolled (letting the browser manage the UI state) or controlled (React owns the state).

  • Uncontrolled <select> – Use the defaultValue prop. React writes the initial value to the DOM once during mounting, then stops updating it. This is the standard approach for setting a default option without managing React state.
  • Controlled <select> – Use the value prop together with an onChange handler. The selected option is always driven by React state, requiring you to update the state on every change.

How React Handles defaultValue Internally

During the mount phase, React stores the defaultValue in a defaultValue field of the internal ReactDOMComponent. The mounting algorithm (implemented in the host component mount logic) checks for this field and writes it to the DOM element via setAttribute or direct property assignment.

After mounting, subsequent renders ignore defaultValue. This mirrors native browser behavior where the attribute only affects the initial state, allowing the user to interact with the element freely without triggering React re-renders.

Setting a Default Value in an Uncontrolled Select

For simple forms where you do not need React to track every change, render an uncontrolled <select> with the defaultValue prop matching the value attribute of your desired option.

function FruitPicker() {
  return (
    <select defaultValue="apple">
      <option value="apple">Apple</option>
      <option value="banana">Banana</option>
      <option value="cherry">Cherry</option>
    </select>
  );
}

React reads defaultValue="apple" once, selects the Apple option during the initial mount, and then lets the user change the selection freely without React interference.

Default Values for Multiple Select

When working with a multiple select element, pass an array of strings to defaultValue to pre-select multiple options.

function MultiFruitPicker() {
  return (
    <select multiple defaultValue={['banana', 'cherry']}>
      <option value="apple">Apple</option>
      <option value="banana">Banana</option>
      <option value="cherry">Cherry</option>
      <option value="date">Date</option>
    </select>
  );
}

During mount, React iterates over the <option> children and marks each matching value as selected. Afterwards, the user can toggle options without triggering React state updates.

Controlled Select Components (Using the value Prop)

For dynamic forms where the selected value must drive UI logic or sync with other components, use a controlled component with the value prop and an onChange handler.

function ControlledFruitPicker() {
  const [fruit, setFruit] = React.useState('banana');

  return (
    <select value={fruit} onChange={e => setFruit(e.target.value)}>
      <option value="apple">Apple</option>
      <option value="banana">Banana</option>
      <option value="cherry">Cherry</option>
    </select>
  );
}

Here, the selected option always reflects the React state (fruit). Changing the state updates the DOM on each render. This approach is necessary when you need to validate, filter, or synchronize the select value with other parts of your application.

Common Pitfalls and Warnings

Do not mix value and defaultValue on the same select element. This triggers a React warning because the component cannot be both controlled and uncontrolled simultaneously.

// This will trigger a warning (see ReactDOMSelect-test.js)
<select value="apple" defaultValue="banana" readOnly />

React warns because value signals that React should control the component, while defaultValue signals that the browser should control it. Choose one approach based on whether you need React to manage the state after the initial render.

Key Implementation Files in the React Source Code

The behavior of defaultValue in React select elements is defined in the following source files within the facebook/react repository:

These files demonstrate how React stores the default selection in a defaultValue field of the internal ReactDOMComponent during the mount phase, writes it to the DOM via setAttribute or property assignment, and subsequently ignores the prop on updates.

Summary

  • Use defaultValue on an uncontrolled <select> to set the initial selected option without managing React state.
  • For multiple selects, pass an array of values to defaultValue to pre-select multiple options.
  • Use value with onChange for controlled components where React must own the selection state.
  • Never mix value and defaultValue on the same element to avoid runtime warnings.
  • React writes defaultValue to the DOM only during the initial mount phase, then ignores it on subsequent renders.

Frequently Asked Questions

What is the difference between defaultValue and value in React select?

The defaultValue prop sets the initial selection for an uncontrolled component, allowing the browser to manage subsequent user interactions. The value prop creates a controlled component where React manages the selection state and updates the DOM on every render. Once you use value, you must provide an onChange handler to update the state.

Can I use defaultValue with a multiple select in React?

Yes, you can use defaultValue with a multiple select by passing an array of strings or numbers that match the value attributes of the options you want pre-selected. For example: defaultValue={['apple', 'banana']}. During the mount phase, React iterates through the options and marks each matching value as selected.

Why does React warn when I use both value and defaultValue on a select?

React warns because a component cannot be both controlled and uncontrolled simultaneously. Using value signals that React should control the component's state, while defaultValue signals that the browser should control it. Mixing them creates ambiguous behavior, so React throws a warning to force you to choose one consistent approach.

How does React set the default value during the mounting phase?

During the mounting phase, React stores the defaultValue in an internal field of the ReactDOMComponent. The mounting algorithm checks for this field and writes it to the DOM element via setAttribute or direct property assignment. After mounting, React ignores defaultValue on subsequent renders, which mirrors native browser behavior where the attribute only affects the initial state.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s https://instagit.com/install.md

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client