Two Ways to Get Selected Option in React

Using controlled and uncontrolled components
Ferenc Almasi β€’ 2023 April 09 β€’ Read time 6 min read
  • twitter
  • facebook
React

Working with form elements in React, such as input or select, can be handled in different ways. Therefore, there are two ways to get the selected option in React: using controlled and uncontrolled components.


Get Selected Option with Controlled Component

The recommended way is to use a controlled component where the state is handled by React. To grab the selected option, we can use the useState hook. Take the following code as an example:

Copied to clipboard! Playground
import React, { useState } from 'react'

const App = () => {
    const [value, setValue] = useState('react');

    return (
        <React.Fragment>
            <h1>Input value: "{value}"</h1>
            <select
                onChange={event => setValue(event.target.value)}
                defaultValue={value}
            >
                <option value="react">React</option>
                <option value="js">JavaScript</option>
            </select>

            <button onClick={() => console.log(value)}>Get state</button>
        </React.Fragment>
    );
}

export default App;
Getting selected option with a controlled component

In this component, we have a select element with two options. We need to attach an onChange event listener to the select element, where we can set the selected value to the value state (using event.target.value). This is what we have done on line:10.

Instead of using the selected attribute on one of the options, we need to use the defaultValue prop on the select element for default values.  

Now whenever we change the option, the new value will be stored inside the value state. Clicking on the button will log the selected value to the console.

Get the selected option with external data

Most of the time, you will be working with external data and building the select options programmatically, usually using an array of objects. Let's see how we can translate the above example to generate the options from an external source:

Copied to clipboard! Playground
import React, { useState } from 'react'

const selectOptions = [
    {
        label: 'React',
        value: 'react'
    },
    {
        label: 'JavaScript',
        value: 'js'
    }
]

const App = () => {
    const [option, setOption] = useState(selectOptions[0]);

    const setSelectedOption = event => {
        const option = selectOptions
            .find(option => option.value === event.target.value)

        setOption(option)
    }

    return (
        <React.Fragment>
            <pre>Input value: "{JSON.stringify(option, null, 4)}"</pre>
            <select
                onChange={setSelectedOption}
                defaultValue={option.value}
            >
                {selectOptions.map(option => (
                    <option value={option.value}>{option.label}</option>
                ))}
            </select>
            <button onClick={() => console.log(option)}>Get state</button>
        </React.Fragment>
    );
}

export default App;
Getting selected option with external data

Here, we store the data for the options inside a selectOptions variable. In a real-world scenario, this data would be fetched from an API. We can set the default state using one of the indexes of the array. In this case, we set it to selectOptions[0].

To set the correct option, we need to use the find method on the selectOptions array. If one of the option.value matches event.target.value, we set the selected option to that object. As for displaying the options, we can use a simple map.

We can use JSON.stringify with two additional parameters to indent the output.

Now whenever we change the select, it will find the correct option from the array and update the internal state of the component using the setOption updater function. The value of the selected option will take the following form:

Copied to clipboard!
{
    label: 'React',
    value: 'react'
}
The value of a selected option

Get Selected Option with Uncontrolled Component

Although the first example is the recommended way to handle state in React, we can also achieve the same behavior with an uncontrolled component. In uncontrolled components, the state is only handled by the DOM. To turn the first example into an uncontrolled component, we simply need to replace the useState hook with a variable:

Copied to clipboard! Playground
import React from 'react'

const App = () => {
    let value = 'react'

    return (
        <React.Fragment>
            <h1>Input value: "{value}"</h1>
            <select
                onChange={event => value = event.target.value}
                defaultValue={value}
            >
                <option value="react">React</option>
                <option value="js">JavaScript</option>
            </select>

            <button onClick={() => console.log(value)}>Get state</button>
        </React.Fragment>
    );
}

export default App;
Getting selected option with an uncontrolled component

Now the value for the defaultValue prop is stored in a regular variable. We can set this variable to event.target.value inside the onChange event on line:10. Again, whenever we click on the button, it will return the selected option.

Keep in mind that you only want to work with uncontrolled components on rare occasions, such as when your form doesn't require client-side validation or you don't depend on the state of fields.

  • twitter
  • facebook
React
Did you find this page helpful?
πŸ“š More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Access 100+ interactive lessons
  • check Unlimited access to hundreds of tutorials
  • check Prepare for technical interviews
Become a Pro

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.