# How to Handle the Selected Attribute for a Select in React with Dynamic Options

> Learn how to correctly manage the selected attribute for dynamic select options in React. Master controlled and uncontrolled components for seamless UI updates. Use value or defaultValue on select, not selected on option.

- Repository: [Meta/react](https://github.com/facebook/react)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Use the `value` prop (for controlled components) or `defaultValue` prop (for uncontrolled components) on the `<select>` element itself, never the `selected` attribute on individual `<option>` elements.**

When building dynamic forms in React, managing the **selected attribute for a select in React** requires understanding how the library internally synchronizes state with the DOM. According to the facebook/react source code, React intercepts the native `selected` property and manages it through specialized binding logic in [`ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/ReactDOMSelect.js).

## Why React Controls the Selected State

React does not allow direct manipulation of the `selected` attribute on `<option>` elements. Instead, the framework uses the `updateOptions` function in [`packages/react-dom-bindings/src/client/ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/client/ReactDOMSelect.js) to synchronize the DOM with your component's state.

When you provide a `value` prop to `<select>`, React runs `updateSelect` on every render (lines 23-25). This function invokes `updateOptions`, which iterates through the option nodes and sets `option.selected = true` for values matching your state (lines 90-98).

## Controlled Components with Dynamic Options

For dynamic lists fetched from an API or computed from state, use the controlled pattern with the `value` prop.

```javascript
function FruitPicker({ options }) {
  const [selected, setSelected] = React.useState('apple');

  return (
    <select
      value={selected}
      onChange={e => setSelected(e.target.value)}
    >
      {options.map(o => (
        <option key={o.id} value={o.id}>
          {o.name}
        </option>
      ))}
    </select>
  );
}

```

In this pattern, `updateOptions` (lines 90-98 in [`ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/ReactDOMSelect.js)) automatically handles the native `selected` property whenever the `options` array or `selected` state changes.

## Uncontrolled Components with Default Values

When you want the browser to manage the selection state but need to specify an initial value, use `defaultValue`.

```javascript
function CountryPicker({ options }) {
  return (
    <select defaultValue="US">
      {options.map(c => (
        <option key={c.code} value={c.code}>
          {c.name}
        </option>
      ))}
    </select>
  );
}

```

During mounting, `initSelect` (lines 52-58 in [`ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/ReactDOMSelect.js)) executes `updateOptions` with `setDefaultSelected = true`. This ensures the browser's default selected state matches your `defaultValue` without React taking control of subsequent changes.

## Handling Multi-Select with Dynamic Arrays

For `<select multiple>` elements, pass an array to `value` or `defaultValue`.

```javascript
function MultiTagSelector({ tags }) {
  const [selectedTags, setSelectedTags] = React.useState(['react', 'js']);

  return (
    <select
      multiple
      value={selectedTags}
      onChange={e => {
        const values = Array.from(
          e.target.selectedOptions, 
          o => o.value
        );
        setSelectedTags(values);
      }}
    >
      {tags.map(t => (
        <option key={t} value={t}>
          {t}
        </option>
      ))}
    </select>
  );
}

```

According to lines 71-84 in [`ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/ReactDOMSelect.js), `updateOptions` builds a lookup map of the array values and marks each matching option as selected. This approach works efficiently even when the `tags` array changes dynamically.

## Critical Implementation Rules from ReactDOMSelect.js

### Never Mix Value and DefaultValue

The source code explicitly warns against mixing these props. Lines 30-41 in [`ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/ReactDOMSelect.js) trigger a development-mode warning if you specify both `value` and `defaultValue` on the same element. Choose one pattern: controlled (`value`) or uncontrolled (`defaultValue`).

### Do Not Set Selected Manually

Setting the `selected` attribute directly on an `<option>` element has no effect in React. The `updateOptions` function (called during every render cycle) iterates through all options and overrides any manual `selected` settings based on the current `value` or `defaultValue` prop.

### Handling the Multiple Prop Change

If you dynamically switch the `multiple` prop, React detects this change in `updateSelect` (lines 25-33). The framework either reapplies the default value or clears the selection to ensure DOM consistency when transitioning between single and multi-select modes.

## Summary

- **Use `value`** for controlled components where React manages the selection state, or **`defaultValue`** for uncontrolled components where the browser manages state.
- **Never use the `selected` attribute** on individual `<option>` elements; React's `updateOptions` function in [`ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/ReactDOMSelect.js) controls this internally.
- **Pass arrays** to `value` or `defaultValue` when using the `multiple` attribute.
- **Ensure re-renders** occur when dynamic option lists change so React can synchronize the DOM via `updateSelect`.
- **Avoid mixing** `value` and `defaultValue` props to prevent development warnings.

## Frequently Asked Questions

### Can I use the selected attribute on individual option elements in React?

No. React explicitly manages the `selected` property of option elements through the `updateOptions` function in [`ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/ReactDOMSelect.js). Setting `selected` manually on an `<option>` has no lasting effect because React overrides it during the reconciliation process to match the `value` or `defaultValue` prop provided to the parent `<select>` element.

### What happens if I mix value and defaultValue on the same select element?

React will display a development-mode warning and the behavior may be unpredictable. According to lines 30-41 in [`ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/ReactDOMSelect.js), these props are mutually exclusive. `value` creates a controlled component where React manages state, while `defaultValue` creates an uncontrolled component where the browser manages state. You must choose one pattern per component.

### How do I handle a select with multiple selection and dynamically generated options?

Use the `multiple` prop combined with an array passed to the `value` prop (for controlled) or `defaultValue` prop (for uncontrolled). When the options array changes dynamically, ensure your component re-renders so React can execute `updateOptions` (lines 71-84 in [`ReactDOMSelect.js`](https://github.com/facebook/react/blob/main/ReactDOMSelect.js)), which builds a lookup map of your array values and marks each corresponding option as selected.

### Why doesn't my select update when the options array changes but the value stays the same?

React's `updateSelect` function runs on every render, but if your `value` prop references the same primitive (e.g., a string ID) while the `options` array changes, the selection should still synchronize correctly. However, if the previously selected value no longer exists in the new options array, the browser will typically show a blank selection. Ensure your state management updates the `value` when the options change if the current selection becomes invalid, triggering React's `updateOptions` to clear or reset the selection appropriately.