Handling Input and Form Events in React – Complete Beginner’s Guide

Forms are one of the most important parts of any web application — they allow users to input data, submit feedback, register accounts, and more.

In React, handling form inputs is slightly different from traditional HTML because React uses component state to manage input values dynamically. This approach ensures that the UI always reflects the latest application state.

In React, form elements like <input>, <textarea>, and <select> can be controlled by React state. These are called controlled components.

When a user types something, the onChange event updates the state, and the state value updates the input field — creating a two-way data binding.

Example: Basic Controlled Input

import React, { useState } from 'react';

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

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

  const handleSubmit = (event) => {
    event.preventDefault();
    alert(`Hello, ${name}!`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>Enter your name:</label>
      <input type="text" value={name} onChange={handleChange} />
      <button type="submit">Submit</button>
    </form>
  );
}

export default NameForm;

Explanation:

  • useState holds the input’s current value.

  • onChange triggers whenever the user types, updating the state.

  • value is tied to the state, making it a controlled input.

  • onSubmit prevents the default page reload and handles the form logic.

Handling Multiple Inputs

If you have more than one field, you can manage them in a single state object.

import React, { useState } from 'react';

function ContactForm() {
  const [formData, setFormData] = useState({ name: '', email: '' });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData((prev) => ({ ...prev, [name]: value }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        name="name"
        placeholder="Name"
        value={formData.name}
        onChange={handleChange}
      />
      <input
        type="email"
        name="email"
        placeholder="Email"
        value={formData.email}
        onChange={handleChange}
      />
      <button type="submit">Submit</button>
    </form>
  );
}

export default ContactForm;

Tip: Always use name attributes to identify which input field is changing.

Handling Checkboxes, Radio Buttons, and Select

React handles other form controls in the same way — by managing their values through state.

Example: Checkbox

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

  return (
    <label>
      <input
        type="checkbox"
        checked={isChecked}
        onChange={(e) => setIsChecked(e.target.checked)}
      />
      Subscribe to newsletter
    </label>
  );
}

Example: Radio Buttons

function GenderForm() {
  const [gender, setGender] = useState('');

  return (
    <div>
      <label>
        <input
          type="radio"
          value="Male"
          checked={gender === 'Male'}
          onChange={(e) => setGender(e.target.value)}
        />
        Male
      </label>
      <label>
        <input
          type="radio"
          value="Female"
          checked={gender === 'Female'}
          onChange={(e) => setGender(e.target.value)}
        />
        Female
      </label>
    </div>
  );
}

Example: Select Dropdown

function CitySelector() {
  const [city, setCity] = useState('Delhi');

  return (
    <select value={city} onChange={(e) => setCity(e.target.value)}>
      <option value="Delhi">Delhi</option>
      <option value="Mumbai">Mumbai</option>
      <option value="Chennai">Chennai</option>
    </select>
  );
}

Uncontrolled Components

If you don’t want React to manage the form state, you can use uncontrolled components with useRef.

import React, { useRef } from 'react';

function UncontrolledForm() {
  const nameRef = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    alert(`Name: ${nameRef.current.value}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" ref={nameRef} placeholder="Enter name" />
      <button type="submit">Submit</button>
    </form>
  );
}

Uncontrolled components are simpler but less flexible when validating or manipulating input data.

Key Takeaways

  • React handles inputs through controlled components using state.

  • onChange and value are essential for two-way data flow.

  • Always call event.preventDefault() to stop page reloads on form submit.

  • Use uncontrolled components for simple use cases.