Tuesday, January 3, 2023

Controlled and Uncontrolled Components in React

As per React documentation ( https://beta.reactjs.org/learn/sharing-state-between-components#controlled-and-uncontrolled-components), Components are of two types-

  • Controlled Component
  • Uncontrolled Component

Controlled Component in React

A component is called controlled when the data in it is passed through props rather than managed through a local state. That way parent component has the control to specify its behavior.

Uncontrolled component in React

A component having local state and no passing of data or calling of function in other component is called an uncontrolled component.

Uncontrolled components are easier to use because they require less configuration as no communication with parent is required. But they're less flexible when you want to coordinate them together.

Controlled components are maximally flexible, but they require the parent components to fully configure them with props.

Controlled Component example

In the example there is a component CitySelect which shows a dropdown to select a city. Which city is selected and what happens when you select another city is controlled through parent component (City.js) by passing props.

CitySelect.js

const options = [
    {value:'IND', label:'India'},
    {value:'USA', label:'USA'},
    {value:'AUS', label:'Australia'},
    {value:'NET', label:'Netherlands'}
]
const CitySelect = (props) => {
    const changeCityHandler = (event) => {
        const option = event.target.options[event.target.selectedIndex];
        props.onChangeHandler(option);
    }
    return(
        <div>
            <label>Select City</label>
            <select value={props.selected} onChange={changeCityHandler}>
            {options.map((option) => (
                <option key={option.value} value={option.value}>{option.label}</option>           
            ))};
            </select>
        </div>
    );
}

export default CitySelect;

Here you can see that selected value for dropdown is determined through props, when you select another city onChange event handler is triggered which ultimately calls a function in parent component through props (props.onChangeHandler(option);).

City.js

import { useState } from "react";
import CitySelect from "./CitySelect";

const City = () => {
    const [city, setCity] = useState({value:'IND', label:'India'});
    
    const getSelectedCity = (cityoption) => {
        setCity(cityoption);
    }
    return(
        <div>
            <span>Selected City- </span>{city.label}
            <hr />
            <CitySelect selected={city.value} onChangeHandler={getSelectedCity}></CitySelect>
        </div>
    );
}

export default City;

You are sending relevant data while calling <CitySelect> tag

<CitySelect selected={city.value} onChangeHandler={getSelectedCity}></CitySelect>

If you keep the state and onChange() event handler logic in CitySelect.js then it has local state and it becomes an uncontrolled component.

Controlled and Uncontrolled component in React form

In a React form if value of an input form element is controlled by React in such a way that the component that renders a form also controls what happens in that form on subsequent user input, then that component is termed as a controlled component.

In a controlled component form input element's value and its mutation is managed through state.

Controlled Component in React form example

Here is a simple form with only a single input field and a submit button.

import { useState } from "react";

const ControlledComponent = () => {
    const [name, setName] = useState('');
    const onChangeHandler = (event) => {
        setName(event.target.value);
    }
    const onSubmitHandler = (event) => {
        event.preventDefault();
        console.log('Name', name);
    }
    return (
        <form onSubmit={onSubmitHandler}>
            <label htmlFor="name">Name: </label>
            <input type="text" id="name" value={name} onChange={onChangeHandler}></input>
            <button type="submit" >Submit</button>
        </form>
    );
}

export default ControlledComponent;

Two important points that makes this component a controlled component.

  1. React does the task of managing the state of the input field meaning managing its value and its mutation. In the input field, value attribute is set to the state value which means the input’s value is always driven by the React state.
  2. There is a onChange() event handler that runs on every keystroke to update the React state. So, the mutation of the value is also captured through state.

Uncontrolled Component in React form example

In an uncontrolled component form data is handled by the DOM itself. Which means you won't be managing state and having event handlers to update the state.

In uncontrolled component you use a ref to get form values from the DOM.

import { useRef } from "react";

const UncontrolledComponent = () => {
    const nameRef = useRef();
    const onSubmitHandler = (event) => {
        event.preventDefault();
        console.log('Name ', nameRef.current.value);
    }
    return (
        <form onSubmit={onSubmitHandler}>
            <label htmlFor="name">Name: </label>
            <input type="text" id="name" ref={nameRef}></input>
            <button type="submit" >Submit</button>
        </form>
    );
}

export default UncontrolledComponent;

As you can see now useState() hook is not used. Instead useRef is used which refers the ref assigned to the ref attribute of name input.

nameRef holds the reference to HTMLElement instance of the name input in its current property. Then using value property, we can get the value of the input element.

nameRef.current.value

That's all for this topic Controlled and Uncontrolled Components in React. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. React Declarative Approach
  2. React Virtual DOM
  3. React create-react-app Project Structure
  4. JavaScript Rest Parameter

You may also like-

  1. ArrayList in Java With Examples
  2. Count Number of Times Each Character Appears in a String Java Program
  3. Java Stream API Interview Questions And Answers
  4. What is Client Side Routing in Angular

No comments:

Post a Comment