Controlled and Uncontrolled Component
Introduction
In React, components can be classified as either controlled or uncontrolled based on how they manage and handle their state and form data. Understanding the difference between these two types of components is crucial for effectively managing state and user input in your applications.
i) Controlled ComponentsControlled components are components where React manages the state. The form data is handled by a React component. The React component that renders the form elements also controls their state.
Characteristics of Controlled Components -State Management: The component's state is maintained in the React component's state.
Data Flow: Data flows from the React component to the form element.
Two-Way Binding: Changes in the form element update the component's state, and changes in the state update the form element.
Event Handling: Every input element has an
onChange
handler that updates the state.
ii) Uncontrolled Components
Uncontrolled components are components where the form data is handled by the DOM itself. React does not manage the form data in its state.Characteristics of Uncontrolled Components:
State Management: The component's state is managed by the DOM.
Data Flow: Data flows directly within the DOM, and React interacts with it using refs.
Direct DOM Access: To access the form data, you use refs to get the current values of the form elements.
Simpler Event Handling: There is no need for
onChange
handlers to update the state.Purpose
The purpose of controlled and uncontrolled components in React is to provide different approaches to handling user input and form state. Both methods have their own use cases and advantages, depending on the requirements of the application.
i) Purpose of Controlled ComponentsControlled components are used to give React complete control over the form data. This approach is beneficial in scenarios where you need fine-grained control over the user input, such as validation, conditional rendering, or any situation where the component's state needs to be tightly synchronized with the form elements.
ii) Benefits of Controlled ComponentsSynchronized State: The state of the form elements is always in sync with the component's state, ensuring consistency.
Validation and Conditioning: Easy to implement input validation and conditionally rendering elements based on the input state.
Single Source of Truth: The form data is managed in one place (the React component state), making the data flow more predictable and easier to debug.
Side Effects Management: You can trigger side effects (e.g., API calls) directly from within the state change handlers.
iii) Use Cases of Controlled Components
Form validation and error handling.Dynamic form fields where form elements depend on each other.
Complex forms where input data affects other parts of the UI.
iv) Purpose of Uncontrolled Components
Uncontrolled components are used when you want the form data to be managed by the DOM itself rather than React. This approach can be useful for simpler forms or when integrating with third-party libraries that require direct access to the DOM.
v) Benefits of Uncontrolled Components
Simplicity: Easier to set up, as you don't need to writeonChange
handlers for each input.Less Code: Fewer state management boilerplate codes, leading to simpler component definitions.
Performance: Potentially better performance for large forms since React doesn't need to re-render on every input change.
vi) Use Cases of Uncontrolled Components
Simple forms where minimal validation is needed.Integration with non-React codebases or third-party libraries that rely on direct DOM access.
Performance-critical applications where reducing React renders is necessary.
When to Use Each
i) Controlled Components
Use controlled components when you need to fully manage and validate form data, and when you need to perform side effects based on the form data changes. They offer more control and predictability.ii) Uncontrolled Components
Use uncontrolled components when you want simpler form handling, and when you do not need to manage the state of form inputs explicitly. They are useful for integrating with non-React code or when performance is a concern.Basic Structure
i) Controlled Component
In a controlled component, the form data is handled by the state within the React component. Every form element (input, select, textarea) maintains its state through React state and updates on every change.
State Management: The input value is stored in the component's state.onChange Handler: Updates the state whenever the input value changes.
Value Prop: The input element's
value
attribute is set to the state variable.Submit Handler: Handles form submission and can access the current state value.
ii) Uncontrolled Component
In an uncontrolled component, the form data is managed by the DOM itself. React accesses the form data using refs, which provide a way to access the DOM nodes directly.
Refs: UseuseRef
to create a reference to the input element.Accessing DOM: Access the input value via
inputRef.current.value
.Simpler State Management: No need to manage the state of the input field in the React component.
Submit Handler: Accesses the value directly from the DOM when the form is submitted.
Example
i) Controlled Componentimport React, { useState } from 'react'; function ControlledComponent() { // State to hold the value of the input field const [value, setValue] = useState(''); // Function to handle the change in the input field const handleChange = (e) => { setValue(e.target.value); }; // Function to handle form submission const handleSubmit = (e) => { e.preventDefault(); console.log('Submitted value:', value); }; return ( <form onSubmit={handleSubmit}> <label> Name: <input type="text" value={value} onChange={handleChange} /> </label> <button type="submit">Submit</button> </form> ); } export default ControlledComponent;
ii) Uncontrolled Component
import React, { useRef } from 'react'; function UncontrolledComponent() { // Reference to the input element const inputRef = useRef(null); // Function to handle form submission const handleSubmit = (e) => { e.preventDefault(); console.log('Submitted value:', inputRef.current.value); }; return ( <form onSubmit={handleSubmit}> <label> Name: <input type="text" ref={inputRef} /> </label> <button type="submit">Submit</button> </form> ); } export default UncontrolledComponent;