What are Controlled and Uncontrolled Components in React JS? Which one to use?

Before diving right into the details, when we talk about "Controlled" and "Uncontrolled" components, it is always referring to the components which are handling forms or form inputs in them.

So in ReactJS every interaction a user does is captured by events that we handle while writing the components in ReactJS. Now there are two approaches in which these interactions can be captured.

Now let's see how we can understand both these approaches in detail.

1. Controlled Components:

Controlled components in React are those in which form data is handled by the state of the component. In Controlled Components forms input values and elements are always driven by the event handlers and values of the input elements are stored and maintained in the state.

Example:

Below is the working code for the "Controlled Component" with 2 inputs in a form:

import { useState } from "react";

function App() {
  const [name, setName] = useState("");
  const [age, setAge] = useState("");

  function handleSubmit() {
    console.log("Name: " + name);
    console.log("Age: " + age);
  }
  return (
    <>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          name="name"
          value={name}
          onChange={(e) => setName(e.target.value)}
        />
        <input
          type="number"
          name="age"
          value={age}
          onChange={(e) => setAge(e.target.value)}
        />
        <input type="submit" value="Submit" />
      </form>
    </>
  );
}

export default App;

Now as we can see in the above example we have two states, one is name and the other one is age, each of the states holds the values respective to their inputs. See when the value is being typed in any of these inputs, the ` OnChange event will be fired and set the value in the state. So this is how we can store and make a controlled component.

2. Uncontrolled Components:

As the name suggests, In uncontrolled Components form data is not controlled by React state anymore. In this scenario form data is managed by DOM (Document Object Model) itself.

Form data and values are traditionally managed and stored are stored on the DOM which means these are not controlled by React State.

Example:

Below is the working code for the "Uncontrolled Component" with 2 inputs in a form:

import { useRef } from "react";

function App() {
  const nameRef = useRef();
  const ageRef = useRef();

  function handleSubmit(ref) {
    console.log("Name: " + nameRef.current.value);
    console.log("Age: " + ageRef.current.value);
  }
  return (
    <>
      <form onSubmit={handleSubmit}>
        <input type="text" name="name" ref={nameRef} />
        <input type="number" name="age" ref={ageRef} />
        <input type="submit" value="Submit" />
      </form>
    </>
  );
}
export default App;

Now if you see in the above example, there is no state managed for the values of the inputs. In this, we used DOM API directly to store the data of the form.

We created two React refs, nameRef and ageRef, and assigned them to the ref attributes of name and age inputs, respectively. This will cause the refs to hold the HTMLElement instances of the elements in their .current property. From .current, we can reference the .value property to get the values of the input elements.

Conclusion

The use of the components depends on which use case you are applying for. If you are a large-scale application then it would be good to go with "Controlled Component." Similarly, if you are building small applications with direct HTML form elements implementation inside the render function and you don’t require the run time change events to do any actions, then it’s much easier to manage using "Uncontrolled components".

Let me know in the comment section, which one and in what scenarios you would like to use these 2 approaches.

Did you find this article valuable?

Support Nikhil Khandelwal by becoming a sponsor. Any amount is appreciated!