Chapter 4 of 15
~11 minEvent Handling
React wraps the browser's native events in its own synthetic event system, but the day-to-day experience of handling clicks, input changes, and form submissions feels very close to plain JavaScript once you know the conventions.
Attaching Event Handlers
Event handlers are passed as props named for the event, in camelCase: `onClick`, `onChange`, `onSubmit`. You pass a function reference, not a function call - `onClick={handleClick}`, never `onClick={handleClick()}`, since the latter would call it immediately during render instead of on click.
Try it yourself
A click handlerfunction ClickCounter() { const [clicks, setClicks] = useState(0); function handleClick() { setClicks(clicks + 1); } return <button onClick={handleClick}>Clicked {clicks} times</button>; } render(<ClickCounter />);
Inline Arrow Functions and Passing Arguments
When a handler needs an argument, wrap it in an inline arrow function so it is not called immediately: `onClick={() => handleSelect(id)}`. This is extremely common for list items where each one needs to know which item was clicked.
Try it yourself
Passing an argument to a handlerfunction FruitList() { const [selected, setSelected] = useState(''); const fruits = ['Apple', 'Banana', 'Cherry']; return ( <div> {fruits.map(fruit => ( <button key={fruit} onClick={() => setSelected(fruit)} style={{ marginRight: 6 }}> {fruit} </button> ))} <p>Selected: {selected || 'none'}</p> </div> ); } render(<FruitList />);
Selected: none
The Synthetic Event Object
React handlers receive a SyntheticEvent - a cross-browser wrapper around the native event with the same familiar API (`event.target`, `event.preventDefault()`, `event.stopPropagation()`). It exists so your event-handling code behaves consistently across browsers without you needing to special-case anything.
Preventing Default Behavior
Forms are the classic case: submitting a `<form>` normally reloads the page, so a form's `onSubmit` handler almost always starts with `event.preventDefault()` to stop that and handle the submission in JavaScript instead.
Try it yourself
Preventing a form from reloading the pagefunction SearchForm() { const [query, setQuery] = useState(''); const [lastSearch, setLastSearch] = useState(''); function handleSubmit(event) { event.preventDefault(); setLastSearch(query); } return ( <form onSubmit={handleSubmit}> <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search..." /> <button type="submit">Go</button> <p>Last search: {lastSearch || 'none yet'}</p> </form> ); } render(<SearchForm />);
Handling Common Input Events
`onChange` fires on every keystroke for text inputs (unlike the DOM's native `change`, which only fires on blur) - this is what makes controlled inputs practical. `onKeyDown`/`onKeyUp` give you access to which key was pressed, useful for things like submitting on Enter.
Coding challenge
Build a component with a text input and a button. Clicking the button should log the current input value into a list of "submitted" messages shown below, and clear the input afterward.
function MessageBox() { // write your code here return null; } render(<MessageBox />);
Answer every question below to mark this chapter as complete.
Quiz Yourself
Score: 0/41. How should you attach a click handler that needs an argument, like `handleSelect(id)`?
2. What is a SyntheticEvent in React?
3. Why do form `onSubmit` handlers typically call `event.preventDefault()`?
4. How does React's onChange for text inputs differ from the native DOM change event?