Controlled & Uncontrolled Components in React
Earlier days of coding required developers to write hundreds of lines of code just to develop a single-page application. This usually involved the traditional Document Object Model (DOM) structure. Making changes to these applications was a challenging and tedious task, as developers had to manually search for the element to be changed and update it accordingly. Even a tiny mistake can lead to application failure. Furthermore, updating DOM was expensive. This is where the component-based approach came into the picture. React has opted for this approach.
React is a JavaScript library used to build user interfaces. It supports two types of components, viz. Controlled components and Uncontrolled components. Both the Controlled and Uncontrolled components are used to represent the React components that render HTML form elements. Whenever we produce a React component that renders an HTML form element, we create either a Controlled component or an Uncontrolled component. Uncontrolled and Controlled components differ in the way they access the data from the form elements(<textarea>, <select>, <input>).
Let's discuss these Controlled and Uncontrolled components in detail.
Controlled Components
The Controlled component renders form elements and controls them by keeping the form data in the component's state.
Instead of the DOM, the component handles the input of the form element. It has functions that govern the data that is passed on every onChange event. The mutable state is kept inside the state property and updated only with the setState() method. The Controlled component takes its current value through props and notifies the changes by the callbacks.
Let's consider an example to understand it in a better way.
import { useState } from "react"; const ControlledInput = () => { const [userName, setUserName] = useState(""); const onUserNameChanged = (e) => { setUserName(e.target.value); }; return ( <div> <div>User name : {userName}</div> <input name="user-name" value={userName} onChange={onUserNameChanged} /> </div> ); };
The input field is Controlled because React sets its value from the state <input value={value} ... />. Whenever we type into the input field, the onChange handler updates the state with the input value accessed from the event object. The value state variable is the source of truth. When we need to access the value entered by the user into the input field, we have to read the value from the state variable. The Controlled components can help access the value of any input field.
Uncontrolled Components
An Uncontrolled component stores its own state internally, and we have to query the DOM with the help of a ref to find its current, a bit more like in traditional HTML. There is no need to write a separate Event handler for each input element in an Uncontrolled component to update the state. It can be used whenever we need the value of the input element ref.
import { useRef } from "react"; const UncontrolledInput = () => { const inputValueRef = useRef(""); const buttonClicked = () => { alert(inputValueRef.current.value); }; return ( <div className="App"> <input type="text" ref={inputValueRef} /> <button onClick={buttonClicked}> Submit </button> </div> ); };
Whenever we need access to the data from Uncontrolled components, we have to use a ref. It allows us to reference a DOM element or class component from within a parent component. Refs allow us to "pull" the value from a field. In the above example, we access the data on the button, click and display it on alert.
In short, we can summarize the highlighting difference between Controlled & Uncontrolled components:
I will recommend using Controlled components to implement forms. However, we might need to use both depending on what the requirement calls for. I hope this blog will help to decide which components to use and how they behave. Feel free to write back to us, if you have a specific case to discuss involving React components.