Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogCoursesPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Courses
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 20 of the React Fundamentals: Build Modern UIs from Scratch course
ReactJune 25, 20264 min read

Controlled Components: Managing Form Input State in React

Master controlled components in React by binding input values to state. Learn to handle multiple form fields and reset state after submission with ease.

ReactFormsControlled ComponentsHooksuseStateWeb Developmentjavascriptfrontend

Previously in this course, we explored handling form submissions by intercepting the default browser behavior. While preventing the page reload is the first step, it doesn't give us access to the data the user typed.

In this lesson, we move from simply "catching" a form event to actively managing the data inside it. By using controlled components, we make React the "single source of truth" for our form data, allowing us to validate, format, and clear inputs in real-time.

Understanding Controlled Components from First Principles

In standard HTML, form elements like <input> or <textarea> maintain their own internal state. When a user types, the browser automatically updates the input's visual value. This is "uncontrolled" because React has no idea what’s happening inside that box unless you specifically reach out to grab it (usually via a ref).

A controlled component flips this logic. Instead of the DOM owning the value, we store the input's value in a React state variable. The input element then reflects that state via the value prop. Whenever the user types, we trigger an onChange event, update the state, and React re-renders the component to display the new value.

This might seem like extra work, but it provides a massive benefit: your UI is always a direct reflection of your application's state.

Worked Example: A Multi-Input Movie Review Form

Let’s advance our movie-browser project by adding a "Review" feature. We need a form that accepts a movie title and a personal rating.

To handle multiple inputs without writing a separate state variable for every single field, we can store our data in a single object.

JSX
import { useState } from CE9178">'react';

function ReviewForm() {
  const [formData, setFormData] = useState({
    title: CE9178">'',
    rating: CE9178">''
  });

  const handleChange = (e) => {
    const { name, value } = e.target;
    // We use the functional update pattern to merge new values
    setFormData((prev) => ({
      ...prev,
      [name]: value
    }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(CE9178">'Submitted Review:', formData);
    
    // Resetting the form
    setFormData({ title: CE9178">'', rating: CE9178">'' });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="title"
        value={formData.title}
        onChange={handleChange}
        placeholder="Movie Title"
      />
      <input
        name="rating"
        type="number"
        value={formData.rating}
        onChange={handleChange}
        placeholder="Rating (1-10)"
      />
      <button type="submit">Submit Review</button>
    </form>
  );
}

Why this works

  1. State Binding: The value prop of each input is tied directly to formData.
  2. Dynamic Keys: By using [name]: value in our handleChange function, we use the input's name attribute as the key in our state object. This allows one function to handle any number of inputs.
  3. Resetting: Because we control the value through state, calling setFormData with empty strings effectively clears the inputs in the UI instantly.

Hands-on Exercise

Modify your existing MovieCard or create a new AddMovieForm component.

  1. Create a form with three inputs: title, director, and year.
  2. Use a single state object to track all three.
  3. Ensure that clicking the "Submit" button logs the object to the console and clears all three input fields.

Common Pitfalls

  • Forgetting onChange: If you provide a value prop but no onChange handler, the input will become read-only. The user won't be able to type anything.
  • Direct Mutation: Never do formData.title = 'New Title'. Always use the setFormData setter function to ensure React triggers a re-render.
  • Missing name attributes: Our handleChange trick relies on e.target.name matching the keys in our state object. If you forget to add the name attribute to your HTML input, the state update will fail.
  • Complexity Overload: If your form gets massive (20+ fields), consider using a library like React Hook Form. But for 90% of use cases, the pattern above is the industry standard.

For a deeper look into the trade-offs, you can revisit React form handling: Controlled vs. Uncontrolled Components. Remember that understanding the React state snapshot mental model will help you debug why your inputs might behave unexpectedly during rapid typing.

Recap

Controlled components turn form inputs into predictable, state-driven UI elements. By binding the value to state and syncing it via onChange, we gain full control over data flow. We’ve learned that managing multiple inputs with a single state object keeps our code clean, and resetting forms is as simple as updating that same state object on submit.

Up next: We'll look at how events propagate through the DOM tree and how to manage them in Event Bubbling and Propagation.

Previous lessonHandling Form SubmissionsNext lesson Event Bubbling and Propagation
Back to Blog

Similar Posts

ReactReactJune 25, 20263 min read

Fetching Data from an API: A Practical React Guide

Master the fetch API in React to retrieve external data. Learn to perform asynchronous requests and store JSON responses in your component state effectively.

Read more
ReactReactJune 25, 20263 min read

Part of the course

React Fundamentals: Build Modern UIs from Scratch

beginner · Lesson 20 of 49

  1. 1

    Introduction to Component-Based Architecture

    4 min
  2. 2

    Understanding the Virtual DOM

    4 min
  3. 3

    Setting Up with Vite

    3 min

Building a Movie Filter Toggle in React: A Beginner's Guide

Master the art of UI state management by adding a filter toggle to your movie app. Learn to control list rendering using boolean state and checkbox inputs.

Read more
ReactReactJune 25, 20264 min read

Rendering Lists of Data in React: A Practical Guide

Learn how to use the map method for list rendering in React. Master the key prop to keep your dynamic movie lists efficient, performant, and bug-free.

Read more
4

Mastering JSX Syntax

4 min
  • 5

    Creating Static Components

    3 min
  • 6

    Styling Components

    3 min
  • 7

    Passing Data with Props

    3 min
  • 8

    Dynamic Movie Cards

    3 min
  • 9

    Component Composition

    3 min
  • 10

    Conditional Rendering

    3 min
  • 11

    Rendering Lists of Data

    4 min
  • 12

    The Key Prop Explained

    4 min
  • 13

    Introduction to React State

    4 min
  • 14

    Managing State with useState

    3 min
  • 15

    Building an Interactive Search Bar

    3 min
  • 16

    Handling Click Events

    4 min
  • 17

    Updating State Based on Previous State

    4 min
  • 18

    Filtering the Movie List

    3 min
  • 19

    Handling Form Submissions

    3 min
  • 20

    Controlled Components

    4 min
  • 21

    Event Bubbling and Propagation

    3 min
  • 22

    Building a Movie Filter Toggle

    3 min
  • 23

    Introduction to Side Effects

    4 min
  • 24

    useEffect Dependencies

    4 min
  • 25

    Fetching Data from an API

    3 min
  • 26

    Handling Loading States

    3 min
  • 27

    Managing Errors

    3 min
  • 28

    Cleanup Functions in useEffect

    3 min
  • 29

    Debouncing Search Input

    3 min
  • 30

    Refactoring for Clean Code

    3 min
  • 31

    Folder Structure Best Practices

    4 min
  • 32

    Extracting Custom Hooks

    3 min
  • 33

    Prop Drilling and Context API

    Coming soon
  • 34

    Polishing the UI

    Coming soon
  • 35

    Finalizing the Movie Browser

    Coming soon
  • 36

    Review of Component Lifecycle

    Coming soon
  • 37

    Review of State Management

    Coming soon
  • 38

    Building a Modal Component

    Coming soon
  • 39

    Introduction to PropTypes

    Coming soon
  • 40

    Performance Optimization Basics

    Coming soon
  • 41

    Handling Browser History

    Coming soon
  • 42

    Working with LocalStorage

    Coming soon
  • 43

    Building a Favorites List

    Coming soon
  • 44

    Handling Media in React

    Coming soon
  • 45

    Introduction to Testing

    Coming soon
  • 46

    Debugging React Apps

    Coming soon
  • 47

    Deployment Basics

    Coming soon
  • 48

    Using External Libraries

    Coming soon
  • 49

    Advanced

    Coming soon
  • View full course