React JSX: selecting "selected" on selected ` can be an array if you have `multiselect` enabled. – tirdadc Apr 28 '17 at 14:56

  • 12
    Rather use `defaultValue` to initialize – dewwwald Oct 04 '17 at 17:19
  • The link from Sophie Alpert now says we should use the State as "The single source of truth". The link is the official answer. :-) – Juanjo May 31 '18 at 14:01
  • What do you have on this `optionsState`? Can you show? – Francisco Souza Aug 14 '19 at 13:35
  • With the current version of react, use 'defaultValue' instead of 'value' on select element. – the_haystacker Nov 21 '19 at 08:29
  • 7
    Try to use defaultValue on is rendered, the must already be available or else it won't work. If you async-load the options after rendering the – user3523091 Apr 03 '20 at 01:14
  • 85

    You could do what React warns you when you try to set the "selected" property of the <option>:

    Use the defaultValue or value props on <select> instead of setting selected on <option>.

    So, you can use options.value on the defaultValue of your select

    Simon Adcock
    • 3,554
    • 3
    • 25
    • 41
    • 9
      If I want to still indicate the option that is currently selected, how would I do this though? The only way I am currently able to actually keep the option selected (and keep the form's state for future POSTing) is by setting select=true. I have tried setting the defaultValue and value props of the select element, but this does not render in the view by setting the correct option to selected in the option menu. Any advice? – The Pied Pipes Apr 23 '15 at 21:35
    • 7
      Example maybe?? – shinzou Jun 11 '18 at 13:07
    • 2
      Not working for me : – Kuartz Jun 07 '19 at 08:47
    • Me neither @Kuartz –  Aug 27 '20 at 14:35
    36

    Here is a complete solution which incorporates the best answer and the comments below it (which might help someone struggling to piece it all together):

    UPDATE FOR ES6 (2019) - using arrow functions and object destructuring

    in main component:

    class ReactMain extends React.Component {
    
      constructor(props) {
        super(props);
        this.state = { fruit: props.item.fruit };
      }
    
      handleChange = (event) => {
        this.setState({ [event.target.name]: event.target.value });
      }
    
      saveItem = () => {
        const item = {};
        item.fruit = this.state.fruit;
        // do more with item object as required (e.g. save to database)
      }
    
      render() {
        return (
          <ReactExample name="fruit" value={this.state.fruit} handleChange={this.handleChange} />
        )
      }
    
    }
    

    included component (which is now a stateless functional):

    export const ReactExample = ({ name, value, handleChange }) => (
      <select name={name} value={value} onChange={handleChange}>
        <option value="A">Apple</option>
        <option value="B">Banana</option>
        <option value="C">Cranberry</option>
      </select>
    )
    

    PREVIOUS ANSWER (using bind):

    in main component:

    class ReactMain extends React.Component {
    
      constructor(props) {
        super(props);
        // bind once here, better than multiple times in render
        this.handleChange = this.handleChange.bind(this);
        this.state = { fruit: props.item.fruit };
      }
    
      handleChange(event) {
        this.setState({ [event.target.name]: event.target.value });
      }
    
      saveItem() {
        const item = {};
        item.fruit = this.state.fruit;
        // do more with item object as required (e.g. save to database)
      }
    
      render() {
        return (
          <ReactExample name="fruit" value={this.state.fruit} handleChange={this.handleChange} />
        )
      }
    
    }
    

    included component (which is now a stateless functional):

    export const ReactExample = (props) => (
      <select name={props.name} value={props.value} onChange={props.handleChange}>
        <option value="A">Apple</option>
        <option value="B">Banana</option>
        <option value="C">Cranberry</option>
      </select>
    )
    

    the main component maintains the selected value for fruit (in state), the included component displays the select element and updates are passed back to the main component to update its state (which then loops back to the included component to change the selected value).

    Note the use of a name prop which allows you to declare a single handleChange method for other fields on the same form regardless of their type.

    Andy Lorenz
    • 2,905
    • 1
    • 29
    • 29
    • Note the line in the constructor `this.handleChange.bind(this);` should be `this.handleChange = this.handleChange.bind(this)`; – Will Shaver May 18 '17 at 22:20
    • for those of you like me who asking them self what the ... means: https://reactjs.org/docs/jsx-in-depth.html#spread-attributes – talsibony Dec 25 '17 at 21:31
    • 1
      @talsibony - that is indeed the spread operator, but in my sample code it just means _insert some other code here_ ! – Andy Lorenz Dec 31 '17 at 16:57
    • @AndyLorenz So in that case I would recommend to remove it... :), or just write comment like // rest of your code – talsibony Jan 01 '18 at 09:08
    15

    I was making a drop-down menu for a language selector - but I needed the dropdown menu to display the current language upon page load. I would either be getting my initial language from a URL param example.com?user_language=fr, or detecting it from the user’s browser settings. Then when the user interacted with the dropdown, the selected language would be updated and the language selector dropdown would display the currently selected language.

    Since this whole thread has been giving fruit examples, I got all sorts of fruit goodness for you.

    • First up, answering the initially asked question with a basic React functional component - two examples with and without props, then how to import the component elsewhere.

    • Next up, the same example - but juiced up with Typescript.

    • Then a bonus finale - A language selector dropdown component using Typescript.


    Basic React (16.13.1) Functional Component Example. Two examples of FruitSelectDropdown , one without props & one with accepting props fruitDetector

    import React, { useState } from 'react'
    
    export const FruitSelectDropdown = () => {
      const [currentFruit, setCurrentFruit] = useState('oranges')
      
      const changeFruit = (newFruit) => {
        setCurrentFruit(newFruit)
      }
      
      return (
        <form>
          <select 
            onChange={(event) => changeFruit(event.target.value)}
            value={currentFruit}
          >
            <option value="apples">Red Apples</option>
            <option value="oranges">Outrageous Oranges</option>
            <option value="tomatoes">Technically a Fruit Tomatoes</option>
            <option value="bananas">Bodacious Bananas</option>
          </select>
        </form>
      )
    }
    

    Or you can have FruitSelectDropdown accept props, maybe you have a function that outputs a string, you can pass it through using the fruitDetector prop

    import React, { useState } from 'react'
    
    export const FruitSelectDropdown = ({ fruitDetector }) => {
      const [currentFruit, setCurrentFruit] = useState(fruitDetector)
      
      const changeFruit = (newFruit) => {
        setCurrentFruit(newFruit)
      }
      
      return (
        <form>
          <select 
            onChange={(event) => changeFruit(event.target.value)}
            value={currentFruit}
          >
            <option value="apples">Red Apples</option>
            <option value="oranges">Outrageous Oranges</option>
            <option value="tomatoes">Technically a Fruit Tomatoes</option>
            <option value="bananas">Bodacious Bananas</option>
          </select>
        </form>
      )
    }
    

    Then import the FruitSelectDropdown elsewhere in your app

    import React from 'react'
    import { FruitSelectDropdown } from '../path/to/FruitSelectDropdown'
    
    const App = () => {
      return (
        <div className="page-container">
          <h1 className="header">A webpage about fruit</h1>
          <div className="section-container">
            <h2>Pick your favorite fruit</h2>
            <FruitSelectDropdown fruitDetector='bananas' />
    
          </div>
        </div>
      )
    }
    
    export default App
    

    FruitSelectDropdown with Typescript

    import React, { FC, useState } from 'react'
    
    type FruitProps = {
      fruitDetector: string;
    }
    
    export const FruitSelectDropdown: FC<FruitProps> = ({ fruitDetector }) => {
      const [currentFruit, setCurrentFruit] = useState(fruitDetector)
      
      const changeFruit = (newFruit: string): void => {
        setCurrentFruit(newFruit)
      }
      
      return (
        <form>
          <select 
            onChange={(event) => changeFruit(event.target.value)}
            value={currentFruit}
          >
            <option value="apples">Red Apples</option>
            <option value="oranges">Outrageous Oranges</option>
            <option value="tomatoes">Technically a Fruit Tomatoes</option>
            <option value="bananas">Bodacious Bananas</option>
          </select>
        </form>
      )
    }
    

    Then import the FruitSelectDropdown elsewhere in your app

    import React, { FC } from 'react'
    import { FruitSelectDropdown } from '../path/to/FruitSelectDropdown'
    
    const App: FC = () => {
      return (
        <div className="page-container">
          <h1 className="header">A webpage about fruit</h1>
          <div className="section-container">
            <h2>Pick your favorite fruit</h2>
            <FruitSelectDropdown fruitDetector='bananas' />
    
          </div>
        </div>
      )
    }
    
    export default App
    

    Bonus Round: Translation Dropdown with selected current value:

    import React, { FC, useState } from 'react'
    import { useTranslation } from 'react-i18next'
    
    export const LanguageSelectDropdown: FC = () => {
      const { i18n } = useTranslation()
      const i18nLanguage = i18n.language
      const [currentI18nLanguage, setCurrentI18nLanguage] = useState(i18nLanguage)
      
      const changeLanguage = (language: string): void => {
        i18n.changeLanguage(language)
        setCurrentI18nLanguage(language)
      }
      
      return (
        <form>
          <select 
            onChange={(event) => changeLanguage(event.target.value)}
            value={currentI18nLanguage}
          >
            <option value="en">English</option>
            <option value="de">Deutsch</option>
            <option value="es">Español</option>
            <option value="fr">Français</option>
          </select>
        </form>
      )
    }
    

    An invaluable resource for React/Typescript

    Dharman
    • 30,962
    • 25
    • 85
    • 135
    taco_friday
    • 469
    • 7
    • 7
    14

    Here is the latest example of how to do it. From react docs, plus auto-binding "fat-arrow" method syntax.

    class FlavorForm extends React.Component {
      constructor(props) {
        super(props);
        this.state = {value: 'coconut'};
      }
    
      handleChange = (event) =>
        this.setState({value: event.target.value});
    
      handleSubmit = (event) => {
        alert('Your favorite flavor is: ' + this.state.value);
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              Pick your favorite flavor:
              <select value={this.state.value} onChange={this.handleChange}>
                <option value="grapefruit">Grapefruit</option>
                <option value="lime">Lime</option>
                <option value="coconut">Coconut</option>
                <option value="mango">Mango</option>
              </select>
            </label>
            <input type="submit" value="Submit" />
          </form>
        );
      }
    } 
    
    Marc L.
    • 3,296
    • 1
    • 32
    • 42
    Rahil Ahmad
    • 3,056
    • 1
    • 16
    • 21
    11

    Main Point - Controlled Component

    You are looking to set up a "Controlled Component". This will require you to set the value on the element as well as handle the on change event to update the value.

    https://reactjs.org/docs/forms.html#controlled-components

    Examples

    https://codepen.io/codyswartz/pen/QWqYNrY

    Simple Functional Component Select Example

    This also includes a default and grays it out.

    const defaultSelectValue = "Select a fruit"
    
    const SelectExample = () => {
      const [selected, setSelected] = useState(defaultSelectValue)
    
      return (
        <>
          <label htmlFor="fruits">Fruits</label>{' '}
          <select
            id="fruits"
            name="fruits"
            defaultValue={selected}
            style={{ color: selected === defaultSelectValue ? "gray" : "black" }}
            onChange={e => setSelected(e.target.value)}
          >
            <option>{defaultSelectValue}</option>
            <option>Banana</option>
            <option>Apple</option>
            <option>Orange</option>
          </select>
    
          <h2>Selected: {selected}</h2>
        </>
      )
    }
    
    // Usage
    <SelectExample />
    

    Dynamic Reusable Example with Default

    This would take a collection of strings using the first as a default.

    const SelectExample = ({ name, items }) => {
      const defaultSelectValue = items[0]
      const [selected, setSelected] = useState(defaultSelectValue)
    
      return (
        <>
          <label htmlFor={name}>{name}</label>{' '}
          <select
            id={name}
            name={name}
            defaultValue={selected}
            style={{ color: selected === defaultSelectValue ? "gray" : "black" }}
            onChange={e => setSelected(e.target.value)}
          >
            {items.map(item => (
              <option key={item} value={item}>
                {item}
              </option>
            ))}
          </select>
    
          <h2>Selected: {selected}</h2>
        </>
      )
    }
    
    // Usage
    <SelectExample
      name="fruits"
      items={['Select a fruit', 'Banana', 'Apple', 'Orange']}
    />
    
    CTS_AE
    • 12,987
    • 8
    • 62
    • 63
    6

    With React 16.8. We can do this with hooks like the following example

    Codesandbox link

    import React, { useState } from "react";
    import "./styles.css";
    
    export default function App() {
      const options = [
        "Monty Python and the Holy Grail",
        "Monty Python's Life of Brian",
        "Monty Python's The Meaning of Life"
      ];
      const filmsByTati = [
        {
          id: 1,
          title: "Jour de fête",
          releasedYear: 1949
        },
        {
          id: 2,
          title: "Play time",
          releasedYear: 1967
        },
        {
          id: 3,
          releasedYear: 1958,
          title: "Mon Oncle"
        }
      ];
      const [selectedOption, setSelectedOption] = useState(options[0]);
      const [selectedTatiFilm, setSelectedTatiFilm] = useState(filmsByTati[0]);
      return (
        <div className="App">
          <h1>Select Example</h1>
          <select
            value={selectedOption}
            onChange={(e) => setSelectedOption(e.target.value)}
          >
            {options.map((option) => (
              <option key={option} value={option}>
                {option}
              </option>
            ))}
          </select>
          <span>Selected option: {selectedOption}</span>
    
          <select
            value={selectedTatiFilm}
            onChange={(e) =>
              setSelectedTatiFilm(
                filmsByTati.find(film => (film.id == e.target.value))
              )
            }
          >
            {filmsByTati.map((film) => (
              <option key={film.id} value={film.id}>
                {film.title}
              </option>
            ))}
          </select>
          <span>Selected option: {selectedTatiFilm.title}</span>
        </div>
      );
    }
    
    sudo bangbang
    • 27,127
    • 11
    • 75
    • 77
    5

    Simply add as first option of your select tag:

    <option disabled hidden value=''></option>
    

    This will become default and when you'll select a valid option will be setted on your state

    Pietro Allievi
    • 386
    • 6
    • 14
    3
    ***Html:***
    <div id="divContainer"></div>
    
    var colors = [{ Name: 'Red' }, { Name: 'Green' }, { Name: 'Blue' }];
    var selectedColor = 'Green';
    
    ReactDOM.render(<Container></Container>, document.getElementById("divContainer"));
    
    var Container = React.createClass({
        render: function () {
            return (
            <div>            
                <DropDown data={colors} Selected={selectedColor}></DropDown>
            </div>);
        }
    });
    
    ***Option 1:***
    var DropDown = React.createClass(
    {
        render: function () {
            var items = this.props.data;
            return (
            <select value={this.props.Selected}>
                {
                    items.map(function (item) {
                        return <option value={item.Name }>{item.Name}</option>;
                    })
                }
            </select>);
        }
    });
    
    ***Option 2:***
    var DropDown = React.createClass(
    {
        render: function () {
            var items = this.props.data;
            return (
            <select>
                {
                    items.map(function (item) {
                        return <option value={item.Name} selected={selectedItem == item.Name}>{item.Name}</option>;
                    })
                }
            </select>);
        }
    });
    
    ***Option 3:***
    var DropDown = React.createClass(
        {
            render: function () {
                var items = this.props.data;
                return (
                <select>
                    {
                        items.map(function (item) {
    
                                                if (selectedItem == item.Name)
                        return <option value={item.Name } selected>{item.Name}</option>;
                    else
                        return <option value={item.Name }>{item.Name}</option>;
                        })
                    }
                </select>);
            }
        });
    
    muthuvel
    • 1,092
    • 10
    • 17
    • 2
      Even though no explanation was given, one wasn't really needed. The multiple ways to approach the same problem was really helpful insight. Thanks – DJ2 Aug 17 '18 at 17:14
    1

    Use defaultValue to preselect the values for Select.

    <Select defaultValue={[{ value: category.published, label: 'Publish' }]} options={statusOptions} onChange={handleStatusChange} />
    
    Joomler
    • 2,610
    • 3
    • 30
    • 37
    1
    if you store objects in a state.
    
    class Studentinformation extends Component
    {
        constructor(props)
     {
       super(props);
       this.handlechange=this.handlechange.bind(this);
       this.handleSubmit=this.handleSubmit.bind(this);
       
       this.state={Studentinfo:{
              Name:'',
              Skill:'Java',
              Address:''
            }};
     }
     handlechange(event)
     {
       const name=event.target.name;
       const value=event.target.value;
    
       this.setState({ Studentinfo:
      {
        ...this.state.Studentinfo,
        [name]:[value]
      }});
     }
     handleSubmit(event)
     {
      event.preventDefault();
     }
     render(){
       return (
      <div>
        <form onSubmit={this.handleSubmit}>
          <label>Name: <input type="text" name="Name" value={this.state.Studentinfo.Name} onChange={this.handlechange}></input></label>
          <br/>
          <label>Skills: 
            <select value={this.state.Studentinfo.Skill} name="Skill" onChange={this.handlechange}>
              <option value="C++" >C++</option>
              <option value="C#">C#</option>
              <option  value="Java">Java</option>
            </select>
            </label>
            <br/>
            <textarea value={this.state.Studentinfo.Address} onChange={this.handlechange}/>
            <br/>
          <input type="submit" value="Submit"></input>
        </form>
      </div>
       );
     }
    
    }
    
    0

    I've had a problem with <select> tags not updating to the correct <option> when the state changes. My problem seemed to be that if you render twice in quick succession, the first time with no pre-selected <option> but the second time with one, then the <select> tag doesn't update on the second render, but stays on the default first .

    I found a solution to this using refs. You need to get a reference to your <select> tag node (which might be nested in some component), and then manually update the value property on it, in the componentDidUpdate hook.

    componentDidUpdate(){
      let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag);
      selectNode.value = this.state.someValue;
    }
    
    William Myers
    • 287
    • 3
    • 4
    0

    Posting a similar answer for MULTISELECT / optgroups:

    render() {
      return(
        <div>
          <select defaultValue="1" onChange={(e) => this.props.changeHandler(e.target.value) }>
            <option disabled="disabled" value="1" hidden="hidden">-- Select --</option>
            <optgroup label="Group 1">
              {options1}
            </optgroup>
            <optgroup label="Group 2">
              {options2}
            </optgroup>
          </select>
        </div>
      )
    }
    
    daino3
    • 4,386
    • 37
    • 48
    0

    I have a simple solution is following the HTML basic.

    <input
      type="select"
      defaultValue=""
      >
      <option value="" disabled className="text-hide">Please select</option>
      <option>value1</option>
      <option>value1</option>
    </input>
    

    .text-hide is a bootstrap's class, if you not using bootstrap, here you are:

    .text-hide {
      font: 0/0 a;
      color: transparent;
      text-shadow: none;
      background-color: transparent;
      border: 0;
    }
    
    Finn
    • 2,707
    • 2
    • 19
    • 28
    0

    if you use Stateless then

    const IndexPage =({states, selectedState}) => {
    return(
        <select id="states" defaultValue={selectedState} name="state">
    {states.map(state=> (
                          <option value={state.id} key={state.id}>{state.name}</option>
                          ))
                          }
                        </select>
    )
    }
    
    Tuan Le Anh
    • 147
    • 7
    • This answer was flagged for review as [Low Quality](https://stackoverflow.com/help/review-low-quality) and could benefit from an explanation. Here are some guidelines for [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer). Code only answers are **not good answers** and are likely to be downvoted as **not useful**. [From Review](https://stackoverflow.com/review/low-quality-posts/29050458) – Trenton McKinney May 25 '21 at 21:48
    • can you please answer on this related question here https://stackoverflow.com/questions/70199775/how-to-display-selected-option-in-select-dropdown-in-react-js-edit-form – Deep Kakkar Dec 03 '21 at 05:49
    0

    Adding selected to an option

    A very common way of setting an input's value is by adding a selected attribute to one of its elements. For example:

    const Select = ({ values, callback, selected }) => {
      return (
        <select
          disabled={disabled}
          readOnly={readonly}
          onChange={({ target: { value } }) => callback(value)}>
          {values.map(([value, text]) => (
            <option selected={selected === value} value={value}>
              {text}
            </option>
          ))}
        </select>
      );
    }
    

    Setting the value for the select

    While this approach closely resembles HTML and feels intuitive, there is an easier way to do the same thing. React provides us with a shared API between , , and where we can use value or defaultValue (depending if the input is controlled or not) to set the field's value.

    Using this API, we minimize the effort of checking for the selected value, as well as making the code easier to read and update as necessary. Here's an example:

    const Select = ({ values, callback, selected }) => {
      return (
        <select
          disabled={disabled}
          readOnly={readonly}
          defaultValue={selected}
          onChange={({ target: { value } }) => callback(value)}>
          {values.map(([value, text]) => (
            <option value={value}>
              {text}
            </option>
          ))}
        </select>
      );
    }
    

    Note that the above implementation uses defaultValue, therefore it implies that the component is uncontrolled. You can convert this Select component into a controlled component by using value instead of defaultValue.

    For a more detailed explanation of the component, as well as usage examples, you can check out the Select component.

    reference: selected-option

    -2

    I got around a similar issue by setting defaultProps:

    ComponentName.defaultProps = {
      propName: ''
    }
    

    <select value="this.props.propName" ...

    So now I avoid errors on compilation if my prop does not exist until mounting.

    Matt Saunders
    • 4,073
    • 7
    • 33
    • 47
    • That's really not solving the problem. You'll get this: Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`. – Jason Rice Feb 21 '19 at 17:52