The concept of controlled and uncontrolled components in React is in relation to forms. In React, form elements typically hold their own internal state, so their functionality differs from other HTML elements. The different ways to obtain the internal state of form elements give rise to controlled and uncontrolled components.
In HTML form elements, they usually maintain their own state and update the UI as the user inputs. This behavior is not controlled by our program. However, by establishing a dependency between the state property in React and the value of form elements, and then updating the state property through the onChange event paired with setState(), we can control the operations that occur in the form during user input. In React, form input elements controlled in this way are called controlled components.
When defining an input box in React, it does not have the bidirectional binding feature seen in Vue with v-model. This means that there is no directive that can combine data with the input box and synchronize the data as the user inputs content into the input box.
When a user inputs content into the input box on the interface, it maintains its own state. This state is not the same as the usual this.state we see. Instead, it is an abstract state on each form element. This enables it to update the UI according to user input. If we want to control the content of the input box, and the content of the input box depends on the value property in the input, we can define a property named username in this.state and specify the value on the input as this property.
However, you will notice that the input content is read-only at this point because the value is controlled by this.state.username. When the user inputs new content, this.state.username does not automatically update. As a result, the content inside the input does not change. At this point, the console usually throws a warning.
This warning actually provides the solution to this problem. We just need to listen to the input content changes with the onChange event of the component and update this.state.username using setState. This way, in the current component, we can control the value of this form element, which is a controlled component.
It's also important to note that although this component is a controlled component, there are drawbacks if it is used as a shared component for invocation. Even though the Input component itself is a controlled component, the calling side loses the control to change the value of the Input component. Therefore, for the calling side, the Input component becomes an uncontrolled component. Using an uncontrolled component's usage pattern to call a controlled component is an anti-pattern. Examples below will be written in Hooks.
If the component provider or the caller need the Input component to be a controlled component, the provider just needs to give up control.
If a form element does not go through state but is modified through ref or directly manipulating the DOM, then its data cannot be controlled through state, and this is what we call an uncontrolled component.
state.value or checked prop.state of a react controlled component:
state.onChange event handler is called.event and updates the application's state.SetState triggers the view to re-render, completing the update of the form component value.value prop, it can be termed as an uncontrolled component.state or props.ref prop needs to be added to access the rendered underlying DOM element.value by adding defaultValue.