Module: Forms and Controlled Components

Uncontrolled Components

Uncontrolled Components

While controlled components offer a lot of power and predictability, they also require more boilerplate code. React also allows you to work with standard HTML form elements directly, without managing their state in React. These are called uncontrolled components.

What are Uncontrolled Components?

In uncontrolled components, the form data is handled by the DOM itself. React doesn't actively control the input's value. Instead, you access the current value directly from the DOM using refs. You typically retrieve the values when the form is submitted.

How do they work?

  1. ref Attribute: You attach a ref attribute to the form element you want to access. This ref provides a direct reference to the underlying DOM node.
  2. Accessing Values: When you need the form data (usually in a submit handler), you access the current value of the input using the current property of the ref.
  3. No State Updates: You don't update React state as the user types. The DOM handles the value updates directly.

Example:

import React, { useRef } from 'react';

function UncontrolledForm() {
  const nameInput = useRef(null);
  const ageInput = useRef(null);

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

    const name = nameInput.current.value;
    const age = ageInput.current.value;

    console.log('Name:', name);
    console.log('Age:', age);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="name">Name:</label>
      <input type="text" id="name" ref={nameInput} />
      <br />

      <label htmlFor="age">Age:</label>
      <input type="number" id="age" ref={ageInput} />
      <br />

      <button type="submit">Submit</button>
    </form>
  );
}

export default UncontrolledForm;

Explanation:

  • useRef(null): We initialize nameInput and ageInput with null. These will hold the references to the input elements.
  • ref={nameInput}: This assigns the nameInput ref to the name input element. After the component mounts, nameInput.current will point to the actual <input> DOM node.
  • handleSubmit: This function is called when the form is submitted.
  • nameInput.current.value: This accesses the current value of the name input field directly from the DOM. Similarly for ageInput.current.value.
  • event.preventDefault(): Prevents the default form submission behavior (page reload).

When to use Uncontrolled Components:

  • Integration with Non-React Code: If you're integrating with existing code that directly manipulates the DOM, uncontrolled components can be easier to work with.
  • Simple Forms: For very simple forms where you only need the values on submission, the reduced boilerplate can be beneficial.
  • Performance Considerations (Rare): In some very specific scenarios, uncontrolled components might offer a slight performance advantage because they avoid unnecessary re-renders. However, this is usually negligible.

Pros and Cons:

Feature Controlled Components Uncontrolled Components
State Management React State DOM
Boilerplate More Less
Real-time Validation Easier More Complex
Predictability High Lower
Integration Easier with React Easier with non-React

Important Considerations:

  • Validation: Real-time validation is more challenging with uncontrolled components. You'll need to manually validate the values when the form is submitted.
  • Accessibility: Ensure proper accessibility practices are followed, as you're relying on the DOM for value management.
  • Complexity: For complex forms with multiple inputs and dependencies, controlled components generally lead to more maintainable code.

In summary:

Uncontrolled components provide a way to work with form elements without React managing their state. They can be useful in specific situations, but controlled components are generally preferred for most React applications due to their predictability and ease of integration with React's state management system. Choose the approach that best suits your project's needs and complexity.