Understanding Controlled and Uncontrolled Components in ReactJS

Controlled and uncontrolled components in ReactJS are two ways of managing the state of a component. Whenever we work with forms in React, an important question arises:
Who should control the input value — React or the DOM?
- If React state controls the input value, it is called a controlled component.
- If the DOM manages the value internally, it is called an uncontrolled component.
Let us understand both approaches with examples.
Controlled components
A controlled component is a component where React controls the input value through state.
Every time the user types something, React updates the state and the input value is derived from that state.
This means the single source of truth is the React state.
Example
In the below example, we have an input of type text and have used the useState hook to manage the state of the input. A value prop on the input element is set to the state value created by useState. The state is updated in the handleChange function, which is passed to the onChange prop of the input.
import React, { useState } from "react"; const ControlledInput = () => { const [value, setValue] = useState(""); const handleChange = (event) => { setValue(event.target.value); }; return <input type="text" value={value} onChange={handleChange} />; }; export default ControlledInput;
Here's a step-by-step explanation of what happens when the input value is updated:
- The user types text inside the input field.
- The onChange event triggers.
- The handleChange function is executed.
- setValue() updates the React state.
- React re-renders the component.
- The input value is updated with the latest state value.
Because React state manages the value, the component becomes very predictable and easy to control.
Why controlled components are powerful?
Controlled components give developers full control over form behavior.
We can esily:
- Validate user input
- Format user input before storing in the state
- Conditionally enable or disable form submission
- Dynamically modify input values based on user interactions
- Show real-time error messages
Uncontrolled components
An uncontrolled component is one where the DOM, rather than React, controls the input value. React has no control over how the input value is changed.
React can access the value when required using a ref.
Example
In this example we use the useRef hook to reference the DOM element directly. The input element has a ref prop that is set to the inputRef variable created using useRef hook. This allows us to access the value of the input directly through inputRef.current.value.
import React, { useRef } from "react"; const UncontrolledInput = () => { const inputRef = useRef(null); const handleSubmit = (event) => { event.preventDefault(); console.log(inputRef.current.value); }; return ( <form onSubmit={handleSubmit}> <input type="text" ref={inputRef} /> <button type="submit">Submit</button> </form> ); }; export default UncontrolledInput;
Here's a step-by-step explanation of what happens when the form is submitted:
- The user types something into the input.
- The DOM internally stores the input value.
- The user clicks the submit button
- handleSubmit runs.
- event.preventDefault() prevents page refresh.
- The value is accessed using inputRef.current.value
So, what is the conclusion? Which one should we use?
The answer is with "Uday Bhai". Yes, you read that correctly! 😂

It is typically advised to use controlled components for more complex scenarios because uncontrolled components have some drawbacks. Here are a few reasons why using uncontrolled components is not a good idea.
-
Lack of Predictability
Uncontrolled components maintain their own internal state, which makes it harder to predict the state of the component at any given time. This can make debugging and maintaining the component more difficult. -
No Parent Control
With uncontrolled components, the parent component has no direct control over the state of the component. This can lead to unexpected behavior and make it difficult to ensure that the component is working as expected. -
Poor Performance
Uncontrolled components can lead to poor performance, especially in large applications, as the component must re-render every time the state changes. This can negatively impact the overall performance of the application. -
Security Issues
Because uncontrolled components have the capacity to alter their own states, they can potentially pose a security risk. Unexpected behaviour and possible security flaws may result from this. -
Complexity
Uncontrolled elements can quickly grow complex, especially when working with a lot of data. This may make it challenging to maintain and troubleshoot the component.
Short answer for your interview:
Controlled components in React are those where the form data is handled by the React component's state, while uncontrolled components rely on the DOM to manage their own state. Controlled components provide better control and predictability, making them more suitable for complex forms and user interactions, whereas uncontrolled components can be simpler to implement but may lead to less predictable behavior and performance issues in larger applications.



