A controlled component is a component whose form elements (like input fields or checkboxes) are controlled by the state
of the application.
const Controlled = () => {
// State to store the input value
const [inputValue, setInputValue] = useState("");
// Event handler for input changes
const handleInputChange = (e) => {
// Update the state with the new input value
setInputValue(e.target.value);
};
return (
<div>
{/* Input controlled by the state */}
<input type="text" value={inputValue} onChange={handleInputChange} placeholder="Type..." />
{/* Display the current state value */}
<p>You typed: {inputValue}</p>
</div>
);
};
export default Controlled
Feature | Controlled Components | Uncontrolled Components |
---|---|---|
Value management | Controlled by React state |
Not controlled by React state |
State updates | Event handlers update React state |
No explicit state update; values accessed directly from DOM |
Refs | Don't depend on useRef() | Commonly uses useRef() to access element values |
Re-rendering | Re-renders on state changes |
Less re-rendering due to decoupled values |
Recommendation | A Recommended and standard practice for form handling 🏆 |
Useful in certain scenarios but less common best practice |
const Controlled = () => {
// State to store the input value
const [inputValue, setInputValue] = useState("");
// Event handler for input changes
const handleInputChange = (e) => {
// Update the state with the new input value
setInputValue(e.target.value);
};
return (
<div>
{/* Input controlled by the state */}
<input type="text" value={inputValue} onChange={handleInputChange} placeholder="Type..." />
{/* Display the current state value */}
<p>You typed: {inputValue}</p>
</div>
);
};
export default Controlled
const Uncontrolled = () => {
// Create a ref to access the input value
const inputRef = useRef(null);
const handleClick = () => {
// Access the input value directly using ref
const value = inputRef.current.value;
alert(`You typed: ${value}`);
};
return (
<div>
{/* Uncontrolled input with ref */}
<input type="text" ref={inputRef} placeholder="Type something..." />
<button onClick={handleClick}>Click</button>
</div>
);
};
export default Uncontrolled
-
State Control: The value of the form element is stored in the component's state.
-
Event Handling: Changes to the form element trigger an event (e.g., onChange for input fields).
-
State Update: The event handler updates the component's state with the new value of the form element.
-
Re-rendering: The component re-renders with the updated state, and the form element reflects the new value.
const Controlled = () => {
// State to store the input value
const [inputValue, setInputValue] = useState("");
// Event handler for input changes
const handleInputChange = (e) => {
// State update
setInputValue(e.target.value);
};
return (
<div>
{/* Event Handling */}
<input type="text" value={inputValue} onChange={handleInputChange} placeholder="Type..." />
{/* Display the current state value */}
<p>You typed: {inputValue}</p>
</div>
);
};
export default Controlled
-
Single Source of Truth: Form element values are managed by React state, ensuring data consistency.
-
Predictable Updates: Facilitates form validation, dynamic rendering, and seamless integration with React's lifecycle methods.
-
Better Control and Maintainability: Offers superior control and manageability compared to uncontrolled components, making them the preferred approach for React form handling.
The preferred and recommended approach for handling forms in React is by using controlled components
.
Maintain seperate state variables
for each input and update them individually using the onChange event
.
By using conditional rendering based on the state and validate input values before updating the state.
Uncontrolled components can be beneficial when integrating with non-React libraries, or when dealing with forms where controlled components are not possible.