Changing of Values
Learn how states are modified and controlled in various HTML elements.
We'll cover the following
If a value is modified, as is the case with text inputs and radio buttons, the corresponding React state is set to the value provided by the user, triggered by the onChange
event. Controlled components now mandate the following procedure:
- When the user inputs text, the value changes.
- The
onChange
event is triggered and processed by the event handler. - The event handler sets the state using the new value.
- React re-renders the user interface and sets
this.state
to the new value. - The user sees their newly provided value on the screen.
This looks normal to the user, and they will not notice that the form works differently behind the scenes and does not reflect usual browser behavior. React fully takes care of the logic in the background and paints a new frame in the user interface.
Changing states
Checkboxes
Checkboxes (<input type="checkbox" />
) work similarly, but their value will remain the same. Checkboxes change their state rather than their value by providing the boolean true
or false
in its checked
property. If React controls the checked
property, the form field is said to be controlled. One can check whether the checkbox is activated (true
) or not (false
) by inspecting e.target.checked
in the event handler, which passes this information to React state. React then takes care of the re-render and shows the status of the checkbox to the user.
Radio buttons
Radio buttons on the other hand, are a kind of a hybrid element. Similar to checkboxes, radio buttons are seen as controlled if React manages their checked
attribute. However, there are often multiple radio buttons containing the same name but different values within the same
document. It would not make sense to set the values of these names to either true
or false
as we are interested in the actual value of the selected radio button. Thus, the value of the radio button is written into the state. We can check whether the selected value in the state is the same as the value of the field with:
checked={this.state.radio === "1"}
We set checked
to true
in this case if the value of the radio button radio
is equal to 1.
Changing state with simple or multiple selects
Let’s start with a simple use case. A simple <select>
list modifies its value just like a text field, then triggers a re-render and finally shows the selected value in the freshly painted user interface. Multiple selects form an exception though.
Other than their counterparts, a simple select list or a simple text input, multiple select lists do
not expect a string value but an array of strings. Annoyingly, we have to construct this array
ourselves as e.target.value
only ever contains a single value, even if multiple options are
possible. The e.target.selectedOptions
property, an object of type HTMLCollection
, can
help us and contains a list of <option>
elements which are currently selected. This object can
easily be transformed into an array using the static array method Array.from()
added in
ES2015. Using Array.map()
, we can further iterate over this array and return a new array
containing all the relevant values:
Array.from(selectedOptions).map((option) => option.value);
The newly created array is then written into the state as a new value. But before that, we check using e.target.multiple
whether we are actually dealing with a <select>
with multiple choices as it is only this <select>
which expects an array as a value.
Alternatively, we could have passed the changeValue
method to the simple select and the changeSelect
method to the select with multiple choices. Because each select would have received its own event handler, we could have avoided the additional check of checking for a multiple
select. However, following the procedure shown above will make your code more resilient to change requests as the type can be easily changed in the future. In the end, it is up to you though.
Get hands-on with 1200+ tech skills courses.