Module: Forms and Controlled Components

Controlled Components

Controlled Components in React

In React, a controlled component is a form element whose value is controlled by React state. This means that instead of the DOM directly managing the form element's value, React manages it. This provides more control over the input and allows for validation, formatting, and other manipulations before the value is actually used.

Why use Controlled Components?

  • Single Source of Truth: The state of your form is entirely managed by React, making your application's data flow predictable.
  • Validation: You can easily validate input as it's being typed, providing immediate feedback to the user.
  • Formatting: You can format the input value (e.g., currency, phone numbers) before it's stored.
  • Conditional Rendering: You can conditionally render parts of your form based on the input value.
  • Easier Testing: Because the state is managed by React, testing becomes simpler.

How do Controlled Components work?

  1. State Initialization: You initialize a state variable to hold the value of the form element.
  2. Value Binding: You bind the value prop of the form element to the state variable.
  3. Event Handling: You create an event handler (e.g., onChange) that updates the state variable whenever the form element's value changes.

Example: A Controlled Input

import React, { useState } from 'react';

function MyForm() {
  const [name, setName] = useState('');

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

  return (
    <div>
      <label htmlFor="name">Name:</label>
      <input
        type="text"
        id="name"
        value={name}
        onChange={handleChange}
      />
      <p>You typed: {name}</p>
    </div>
  );
}

export default MyForm;

Explanation:

  • useState(''): Initializes a state variable name with an empty string. setName is the function to update this state.
  • value={name}: Binds the value prop of the input element to the name state variable. This means the input's displayed value will always reflect the value of name.
  • onChange={handleChange}: Attaches the handleChange function to the onChange event of the input element. This function will be called every time the input's value changes.
  • handleChange(event): This function receives the event object. event.target.value contains the new value of the input. setName(event.target.value) updates the name state variable with the new value.

Controlled Components for Other Form Elements

The same principle applies to other form elements like <textarea>, <select>, and <checkbox>.

Example: Controlled Textarea

import React, { useState } from 'react';

function MyTextarea() {
  const [message, setMessage] = useState('');

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

  return (
    <div>
      <label htmlFor="message">Message:</label>
      <textarea
        id="message"
        value={message}
        onChange={handleChange}
      />
      <p>You typed: {message}</p>
    </div>
  );
}

export default MyTextarea;

Example: Controlled Select

import React, { useState } from 'react';

function MySelect() {
  const [fruit, setFruit] = useState('apple');

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

  return (
    <div>
      <label htmlFor="fruit">Select a fruit:</label>
      <select id="fruit" value={fruit} onChange={handleChange}>
        <option value="apple">Apple</option>
        <option value="banana">Banana</option>
        <option value="orange">Orange</option>
      </select>
      <p>You selected: {fruit}</p>
    </div>
  );
}

export default MySelect;

Example: Controlled Checkbox

import React, { useState } from 'react';

function MyCheckbox() {
  const [isChecked, setIsChecked] = useState(false);

  const handleChange = (event) => {
    setIsChecked(event.target.checked);
  };

  return (
    <div>
      <label htmlFor="agree">Agree to terms:</label>
      <input
        type="checkbox"
        id="agree"
        checked={isChecked}
        onChange={handleChange}
      />
      <p>Agreed: {isChecked ? 'Yes' : 'No'}</p>
    </div>
  );
}

export default MyCheckbox;

Key Takeaways:

  • Controlled components are fundamental to building robust and manageable forms in React.
  • They provide a clear and predictable data flow.
  • They enable powerful features like validation and formatting.
  • Always remember to bind the value prop and handle the onChange event to create a truly controlled component.