<select></select>
lists hold the state of one or more <option></option>
elements that are selected. React does not change any of these values. If you feel comfortable using the form state, you can keep using it without issues and nothing changes for the development of your components.uncontrolled
component is notified of a change via the onChange
event and can process the username further if necessary. As React only reacts passively and is simply notified of changes in the text field, we still refer to these types of components as uncontrolled components.onChange
event has been triggered, the React state can update safely. However, the text field would not update if changes to values of the React state had been made elsewhere in the application (for example due to a response in an asynchronous request).value
attribute is set. From this point on, React expects the developer to synchronize the React state with the form field state. If we only want to set an initial value without converting the complete component into a controlled component, React allows us to define a defaultValue
attribute instead of the usual value
attribute, the equivalent being defaultChecked
for checkboxes and radio buttons. The element itself will stay uncontrolled but show an initial value or status.value
attribute which we receive from the state and also derive the changed value and pass it back to the state.Controlled
component does not look very different from the Uncontrolled
component. The defining difference that turns this component into a controlled
one rather than uncontrolled
lies in line 29. The value
attribute of this <input />
indicates to React that it should now control the form element and that changes to the input field should be reflected in the state. In order to pass changes to the React state, it is important to define the onChange
handler to keep the form field and React state in sync. Failing to do that, will result in input fields that do not update and is — perhaps unsurprisingly — a mistake made relatively often.value
attribute is only ever allowed to be a string but never undefined
or null
.select
elements that have the multiple
attribute are an exception to the rule. The value
attribute in this case needs to be an array (rather than a string).value
attribute for a <select>
field. But normally an <option>
is selected by setting its selected
attribute in HTML. React works a little different and controls the value with another value
attribute. The same applies to the <textarea>
element (which usually indicates its initial value with the textContent
attribute).value
attribute for the input
, textarea
and select
elements (with the exceptions of checkbox
and radio
inputs). This attribute always has to be a string or, in the case of a select
with a multiple
attribute, an array of strings.checked
).input
elements not listed like email
, date
and range
work exactly the same.changeValue
, changeCheckbox
and changeSelect
.onChange
events in their corresponding form elements and are passed an object of type SyntheticEvent
. We access properties of the target
property of the SyntheticEvent
via ES2015 object destructuring in order to update React state.<input type="text" />
, <input type="radio" />
and <textarea />
, we pick name
and value
, for <input type="checkbox" />
elements name
and the checked
property are important, whereas select
elements also need to provide a name
and whether a selection is offered to the user or a multiple select (with value
or selectedOptions
). We can find out whether we're dealing with a simple or multiple select by inspecting the multiple
property with e.target
.onChange
event. Controlled components now mandate the following procedure:onChange
event is triggered and processed by the event handler.this.state
to the new value.<input type="checkbox" />
) work in a similar fashion 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 the checked
property is controlled by React, 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 showing the status of the checkbox to the user.checked
attribute is managed by React. 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 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.<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.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 furthermore iterate over this array and return a new array containing all the relevant values: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.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 I have 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.name
attribute as the key in the above example to save their value in state. This can come in handy while working with server-side React and if forms are automatically generated and processed. It is not a requirement though: theoretically neither a name
attribute nor the exact match of the state name and the name
attribute is needed.value
or checked
attribute needs to be controlled by React while the developer needs to manually react to changes.value
attribute.