Understanding Controlled And Uncontrolled Components In React

One of the key concepts in React is how to manage form elements and their state. This is typically done using either controlled or uncontrolled components. Understanding the differences between these two approaches is crucial for building effective and maintainable React applications.

Controlled components

Controlled components are those where React handles the form data through its state.

This means that form data is maintained in the component’s state and changes to the form data are handled by event handlers in React. Whenever the user interacts with the input, the component’s state is updated, and React re-renders the component to reflect the new state.

Here’s an example of a controlled input component:

import React, { useState } from 'react';

function ControlledInput() {
  const [value, setValue] = useState('');

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

  return (
    <input
      type="text"
      value={value}
      onChange={handleChange}
    />
  );
}

In this example, the value of the input is controlled by the component’s state, which is managed by React. Whenever the user types into the input, the handleChange function is called, which updates the value state, causing React to re-render the component with the new value.

Uncontrolled Components

Uncontrolled components are those where the form data is handled by the DOM itself.

In other words, the form data is stored in the DOM rather than in the component’s state. To access the form data, we use refs.

import React, { useRef } from 'react';

function UncontrolledInput() {
  const fileInputRef = useRef(null);

  const handleSubmit = (event) => {
    event.preventDefault();

    const formData = new FormData();
    formData.append('profilePicture', fileInputRef.current.files[0]);

    // Simulate a form submission
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label htmlFor="profilePicture">Profile Picture:</label>
        <input type="file" id="profilePicture" ref={fileInputRef} />
      </div>
      <button type="submit">Upload Profile</button>
    </form>
  );
}

In this example, the value of the input is not directly managed by React. Instead, we use a ref (fileInputRef) to access the current value of the input when the form is submitted.

Differences between controlled and uncontrolled components

Feature Controlled Components Uncontrolled Components
Data Handling Managed by React state Managed by the DOM
State Management Uses component state (useState, setState) Uses refs to access form values
Form Validation Easier to implement, as data is in state More complex, as we need to access DOM directly
Default Values Set via React state Set via defaultValue attribute in JSX
Event Handling Requires onChange handlers to update state No need for onChange handlers to update state
Re-rendering Component re-renders on every change in input value Does not re-render on input changes
Complexity More code required for state management and event handling Does not re-render on input changes
Single Source of Truth React component state DOM element
Use Case Complex forms with dynamic interactions and validations Simple forms with basic input handling
Performance Can be less performant due to frequent re-renders Potentially more performant for simple forms

Which Should We Use?

Choosing between controlled and uncontrolled components depends on our specific use case.

Use Controlled Components When:

  • We need tight control over the form data and validation.
  • We want to provide real-time feedback and validation to the user.
  • We have complex forms with interdependent fields.

Use Uncontrolled Components When:

  • We have simple forms with minimal validation requirements.
  • We are quickly prototyping or building a small application.
  • We are integrating with non-React code that expects traditional DOM-based form handling.

In general, controlled components are the preferred approach in most React applications, as they provide more predictability and control over the form data.

However, uncontrolled components can be a valid choice in certain situations, especially for simpler forms or when integrating with non-React code.

Conclusion

Both controlled and uncontrolled components have their place in React development. Controlled components offer greater control and are better suited for complex forms and data handling, while uncontrolled components can be simpler and more suitable for straightforward use cases.

By choosing the right approach for our specific requirements, we can ensure that our forms are easy to manage, validate, and integrate with the rest of our application.

Need help on your Ruby on Rails or React project?

Join Our Newsletter