Lesson 9 - Forms In React

9.3 - Controlled Vs. Uncontrolled Components

In this chapter, we'll briefly compare controlled and uncontrolled components, providing supportive examples to illustrate the differences.

Controlled Component A controlled component is one where the component’s state controls the elements. This means that the data is handled by a React component, and you have full control over the data.

With the support of the React state, the controlled component becomes the unavoidable element for managing user interactions like form handling.

The following example demonstrates a controlled component.

import React, { useState } from 'react';

const App = () => {
 const [inputValue, setInputValue] = useState('');

 const handleChange = (event) => {
 setInputValue(event.target.value);
 };

 const handleSubmit = (event) => {
 event.preventDefault();
 alert('Submitted value: ' + inputValue);
 };

 return (
 <form onSubmit={handleSubmit}>
 <input
 type="text"
 value={inputValue}
 onChange={handleChange}
 />
 <button type="submit">Submit</button>
 </form>
 );
};

Here, we designed a form containing an input field with controls like value, onChange, etc. We also created some control functions like handleChange() and handleSubmit().

The handleChange() function detects changes in the input field and performs the necessary actions, such as updating the state. The handleSubmit() function validates the final submission of the form, ensuring that all required conditions are met before processing the data.

Uncontrolled Component An uncontrolled component is one where the data is handled by the DOM itself. Instead of using state to manage the data, you use refs to directly access form values.

The uncontrolled components provide you with limited control over managing user interaction.

Take a look at the following example of the uncontrolled component.

import { useRef } from "react";

const App = () => {
 const inputRef = useRef(null);

 const handleSubmit = (event) => {
 event.preventDefault();
 alert('Submitted value: ' + inputRef.current.value);
 };

 return (
 <form onSubmit={handleSubmit}>
 <input type="text" defaultValue="initial value" ref={inputRef} />
 <button type="submit">Submit</button>
 </form>
 );
};

You can notice that we didn't use any control component like useState. Instead, we used the useRef to capture the user data.

The function handleSubmit() just shows the input provided by the user.

The following table provides a quick illustration of controlled and uncontrolled components.

Controlled ComponentUncontrolled Component
The controlled component is under the control of the component’s state.The Uncontrolled Component is under the control of DOM.
Internal state is not maintained.Internal state is maintained.
Controlled components accept the current value as props.You can use refs to access form values directly from the DOM.
Controlled components provide you with better control of the form data and values.Uncontrolled components provide limited control over form values and data.
Controlled components are maintained by the parent component.Uncontrolled components are maintained by the DOM itself.