Posted on 5/15/2025 8:09:16 PM by Admin

Handling Forms in React: Introducing Controlled Components

Now that we have already covered the props, conditional rendering, events, and states, it's time to move forward to handling user input through forms. Any web application is incomplete without a form, whether it is a contact form, a complex data entry form, or a search bar. React provides a powerful way to handle forms, called Controlled Components, which we will explore in this article.

Forms in React

Typically, form elements in HTML, such as <input>, <textarea>, and <select>, handle their own internal states. When the user enters some value, the browser updates their values directly within the DOM. To retrieve these values, we often need to interact with the DOM, which could be an overhead in certain situations and does not align with React's component-centric nature.

React takes a different approach when it comes to managing user input via the forms. Instead of letting elements handle their own state, React uses Controlled Components to manage their state. This means that your form data resides in a React component, and the element just reflects that state. This state-to-UI data flow is one of the core principles of React and offers many advantages in form handling in React.

What is a Controlled Component?

A form element that is controlled by React's state is referred to as a Controlled Component. When a user enters a value in a form field, a React-defined event handler is triggered instead of the DOM directly updating the value of the element. The event handler updates the element's state and re-renders the component to display the new value.

You may think that defining an event handler just to update the value of the element is an extra step, but in fact, it provides a level of control and predictability over the form data and contributes to the robustness and maintainability of the application. Besides, by joining the form data with the component's state, you get immediate access to the form data to manipulate it, validate the input, enable/disable other elements based on the value, and use it in other parts of your component.

That being said, let's put this into action.

Connecting Form Elements to React State

To get a controlled component, we first need to create a connection between the element's value property and React's state. To do so, let's first create a basic form:


import React, { useState } from 'react';

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

  return (
    <input type="text" value={name} onChange={(event) => setName(event.target.value)} />
  );
}

export default RegisterForm;

In the above code, we have used the useState() hook to declare and initialize the state variable 'name'. The setName updates its value when the function is triggered. Initially, the state variable is empty. Moreover, we have bound the 'value' property of the input element with the state variable 'name' so the input field always reflects the value of the 'name'.

Furthermore, we have called the onChange() event to update the state of the state variable. It is triggered when the user changes the value of the input field. In our example, we have assigned a function that receives an event object to the onChange property. The element that triggered the event is given by the event.target. The event.target.value reflects the current value of the DOM element, and setName(event.target.value) updates the name state when the new value is entered in the field.

Whenever the state of the element is changed, the component is re-rendered. Since the value attribute is connected to the name, the input field is updated to reflect the new value. This is how a controlled behavior is achieved. The component state controls the value of the form element.

Displaying the Updated Form Values

Since the form values are stored in the component's state, you can easily manipulate and display them on your page, as the following example shows:


import React, { useState } from 'react';

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

  return (
    <div>
      <input type="text" placeholder="Name" value={name} onChange={(event) => setName(event.target.value)}
      />
      
      <p>Name: {name}</p>
    </div>
  );
}

export default RegisterForm;

The entire code is the same as the previous one. I have only added a <p> tag before closing the div in the return statement. Now, to see this in action, go to App.js and add the following code:


import React from 'react';
import ControlledCmp from './ControlledComponent';

function App() {
  return (
      <ControlledCmp/>
  );
}

export default App;

When you run this app, you will see that as you enter a value in the input field, the paragraph tag is updated immediately in real-time.

Handling the Form Submissions

Typically, when the user has filled the form, they submit it. React also uses the onSubmit() event to handle submissions. To understand this, let's update our ControlledComponent.js:


import React, { useState } from 'react';

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

  const submitHandler = (event) => {
    console.log('Form submitted!');
    console.log('Name:', name);
  };

  return (
    <form onSubmit={submitHandler}>
      <input type="text" placeholder="Name" value={name} onChange={(event) => setName(event.target.value)} />
      
      <button type="submit">Submit</button>
    </form>
  );
}

export default RegisterForm;

In the above code, I have added the form tag and called the onSubmit event that triggers the submitHandler() event. When the user hits the Submit button, the submitHandler() event is triggered, and the messages are logged to the console. However, you won't be able to see it because, by default, the browser reloads the page upon form submission, and the values are overwritten automatically. To prevent this, we can use the event.preventDefault() method in our submitHandler() as follows:


const submitHandler = (event) => {
	event.preventDefault();
    console.log('Form submitted!');
    console.log('Name:', name);
  };

Now, we can see the output in the console.

There is a lot more about handling the forms in React, but on the beginner level, understanding these basics is highly crucial. This is the standard way React handles the forms. You get high control over form data by updating the element's values via the component state and managing updates through the event handlers. This helps in achieving highly interactive and user-friendly forms. I highly recommend you to get a good hands-on on these concepts. In the next article, we will learn how to apply styling to the elements in React.


Sharpen Your Skills with These Next Guides