In React, onChange fires immediately as a controlled input's value changes, functionally closer to the native DOM's input event than its actual change event, which normally only fires once an input loses focus after its value changed. This makes onChange the standard way to keep a piece of React state continuously synchronized with an input's current value in a controlled component pattern, reading the new value from event.target.value inside the handler and passing it to a state setter on every change.
1Understanding onChange
In React, onChange fires immediately as a controlled input's value changes, functionally closer to the native DOM's input event than its actual change event, which normally only fires once an input loses focus after its value changed. This makes onChange the standard way to keep a piece of React state continuously synchronized with an input's current value in a controlled component pattern, reading the new value from event.target.value inside the handler and passing it to a state setter on every change.
React's onChange behaves like the native input event, firing on every keystroke, not like the native DOM change event, which normally only fires once focus leaves the field — this distinction matters if you're translating expectations from vanilla JavaScript DOM events.
import { useState } from 'react';
function NameInput() {
const [name, setName] = useState('');
const handleChange = (event) => setName(event.target.value);
return (
<>
<input value={name} onChange={handleChange} />
<p>Hello, {name}</p>
</>
);
}2Practical Example
Here is a real-world application of onChange showing how it is used in production React code.
import { useState } from 'react';
function Subscribe() {
const [checked, setChecked] = useState(false);
const handleChange = (event) => setChecked(event.target.checked);
return <input type="checkbox" checked={checked} onChange={handleChange} />;
}3Best Practices
Follow these guidelines when working with onChange:
1. Read the new value from event.target.value inside an onChange handler and pass it directly to a state setter, for the standard controlled-input pattern
2. Pair a controlled input's value prop with its onChange handler together — a value prop without an onChange handler makes the input read-only and typically triggers a React warning
3. Use event.target.checked instead of event.target.value specifically for checkbox and radio inputs, since their relevant changed property is a boolean, not a string
Tip: React's onChange behaves like the native input event, firing on every keystroke, not like the native DOM change event, which normally only fires once focus leaves the field — this distinction matters if you're translating expectations from vanilla JavaScript DOM events.
import { useState } from 'react';
function NameInput() {
const [name, setName] = useState('');
const handleChange = (event) => setName(event.target.value);
return (
<>
<input value={name} onChange={handleChange} />
<p>Hello, {name}</p>
</>
);
}