Skip to main content

Common Events: `onChange` (Part 2) #43

📖 Introduction

After learning how to handle clicks with onClick, the next most important event in web applications is onChange. This event is the key to creating interactive forms and handling user input in elements like text fields, text areas, and select dropdowns.

This article will cover how to use the onChange event handler to read user input and introduce the fundamental React pattern of a controlled component, where React state is the single source of truth for an input's value.


📚 Prerequisites

Before we begin, please ensure you have a solid grasp of the following concepts:

  • React Event Handlers: You should be comfortable with the onClick handler and the concept of passing functions as props.
  • The useState Hook: A basic understanding of how to declare a state variable and get its setter function is required.
  • HTML Forms: Familiarity with the <input> and <form> elements.

🎯 Article Outline: What You'll Master

In this article, you will learn:

  • The onChange Event: How to use the onChange handler to respond to changes in form inputs.
  • Accessing Input Values: How to get the current value of an input from the event object using e.target.value.
  • Controlled Components: The core React pattern for forms, where an input's value is controlled by React state.
  • A Practical Example: Building a simple, interactive form that updates as the user types.

🧠 Section 1: The Core Concept: Handling Input Changes

In HTML, form elements like <input> naturally keep track of their own state. When you type into a text field, the browser's DOM holds the current value.

In React, we often want the component's state to be the "single source of truth" for the input's value. This is called a controlled component. This pattern allows React to control what's in the input field, making it easier to validate input, format data, or react to changes.

The onChange event is the bridge that makes this possible. It fires every time the user changes the value of the input (e.g., on every keystroke in a text field). Inside our onChange handler, we can get the new value and update our component's state, which then causes the component to re-render with the updated value in the input.


💻 Section 2: Building a Controlled Input

Let's build a simple form with a single text input that displays what the user is typing in real-time.

// code-block-1.jsx
import React, { useState } from 'react';

export default function SimpleForm() {
// 1. Declare a state variable to hold the input's value
const [inputValue, setInputValue] = useState('');

// 2. Create an event handler for the onChange event
function handleChange(event) {
// 3. Update the state with the input's new value
setInputValue(event.target.value);
}

return (
<div>
<form>
<label>Your Name:</label>
<input
type="text"
// 4. The input's value is driven by the state variable
value={inputValue}
// 5. The onChange handler updates the state
onChange={handleChange}
/>
</form>
{/* Display the current state value below the form */}
<p>You are typing: {inputValue}</p>
</div>
);
}

Step-by-Step Code Breakdown:

  1. useState(''): We initialize a state variable inputValue to an empty string. This will be the single source of truth for our input field.
  2. function handleChange(event): We define our event handler. It receives the SyntheticEvent object as an argument.
  3. setInputValue(event.target.value): This is the most important part. event.target refers to the DOM node that triggered the event (the <input>). event.target.value gives us its current value. We then call our state setter function to update inputValue with this new value.
  4. value={inputValue}: We explicitly set the value prop of the <input> to our state variable. This makes it a controlled component. The input will always display whatever is in the inputValue state.
  5. onChange={handleChange}: We wire up our handler to the onChange event.

The Data Flow Cycle:

  1. User types a character.
  2. The onChange event fires on the <input>.
  3. The handleChange function is called.
  4. handleChange calls setInputValue with the new value from event.target.value.
  5. React triggers a re-render of the component with the new inputValue state.
  6. The <input>'s value prop receives the new state, and the input displays the updated text.

This cycle happens on every keystroke, ensuring that your React state and the form input are always in sync.


✨ Section 3: Best Practices

  • Always Use value with onChange: When creating a controlled component, always provide both the value and onChange props to the input. Forgetting the value prop means the input is no longer controlled by React. Forgetting the onChange handler means the user won't be able to type in the field (because the value is locked to the state, and there's no way to update the state).
  • Initialize State: Always initialize the state for your inputs, even if it's just an empty string (''). This prevents the component from switching between being "uncontrolled" and "controlled," which can cause warnings.
  • Use for All Form Elements: The onChange event works similarly for <textarea> and <select> elements, making it the universal tool for handling form inputs in React.

💡 Conclusion & Key Takeaways

The onChange event is fundamental to creating interactive forms in React. By combining it with the useState hook, you can create "controlled components" where React state is the single source of truth, giving you complete control over your form data.

Let's summarize the key takeaways:

  • onChange Fires on Input Change: It's the standard event for handling user input in form elements.
  • event.target.value Holds the Data: You can access the current value of the input through the event object.
  • Controlled Components are the Standard: The pattern of linking an input's value to state and updating it with onChange is the idiomatic way to handle forms in React.
  • The Data Flow is Circular: User input triggers onChange, which updates state, which causes a re-render, which updates the input's value.

Challenge Yourself: Create a component with a <select> dropdown that has three options (e.g., "Red", "Green", "Blue"). Use useState and an onChange handler to keep track of the selected color. Display the currently selected color in a <p> tag below the dropdown.


➡️ Next Steps

You can now handle clicks and input changes, the two most common user interactions. In the next article, "Common Events: onSubmit (Part 3)", we will learn how to handle the submission of an entire form.

Thank you for your dedication. Stay curious, and happy coding!


glossary

  • onChange: A React event handler that is triggered whenever the value of a form element (like <input>, <textarea>, or <select>) is changed by the user.
  • Controlled Component: A form element whose value is controlled by React state. The component's state is the "single source of truth," and the input's value is updated only when the state changes.
  • event.target.value: The property on the event object that contains the current value of the input element that triggered the event.

Further Reading