Two Ways to Get Selected Option in 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:
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;
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:
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;
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:
{
label: 'React',
value: 'react'
}
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:
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;
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.
Rocket Launch Your Career
Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies: