React components can be classified into two categories based on how they manage form data: Controlled and Uncontrolled components.

Controlled component

A Controlled component is a component in which the value of the input field is controlled by React state. The component itself manages the state of the input and updates the state when the user interacts with the input field. Controlled components use the value attribute of the input element to receive the value from the state and use the onChange event to update the state with the new value.

Here’s an example of a Controlled component:

import React, { Component } from 'react';

class ControlledComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ''
    };
  }

  handleInputChange = (event) => {
    this.setState({ inputValue: event.target.value });
  }

  handleSubmit = (event) => {
    event.preventDefault();
    console.log('Submitted value: ', this.state.inputValue);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Enter a value:
          <input
            type="text"
            value={this.state.inputValue}
            onChange={this.handleInputChange}
          />
        </label>
        <button type="submit">Submit</button>
      </form>
    );
  }
}

export default ControlledComponent;

Uncontrolled component

Uncontrolled component is a component in which the value of the input field is managed by the browser. The component does not manage the state of the input, and instead relies on the browser to update the input field value when the user interacts with it. Uncontrolled components use the defaultValue attribute of the input element to set the initial value of the input.

Here’s an example of an Uncontrolled component:

import React, { Component } from 'react';

class UncontrolledComponent extends Component {
  handleSubmit = (event) => {
    event.preventDefault();
    console.log('Submitted value: ', this.input.value);
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Enter a value:
          <input
            type="text"
            defaultValue=""
            ref={(input) => this.input = input}
          />
        </label>
        <button type="submit">Submit</button>
      </form>
    );
  }
}

export default UncontrolledComponent;

The choice between Controlled and Uncontrolled components depends on the requirements of the specific use case. Controlled components are useful when you need to perform validation on the input before submission or when you need to manipulate the input value. Uncontrolled components are useful when you have a simple form that does not require complex validation or manipulation of the input value.