Events
Chapter 3's onClick={() => setCount(count + 1)} was already an event handler, just introduced without much explanation. This chapter covers the pattern properly — naming handlers, the most common event types, reading information off the event itself, and the one JSX-specific gotcha that catches almost everyone coming from plain HTML.
Inline vs Named Handler Functions
Either style works the same way — what matters is passing a function reference, not the result of calling one. onClick={handleClick} is correct; onClick={handleClick()} would call handleClick immediately during render and pass its return value as the handler instead, which is almost never what's intended.
onClick={handleClick()} runs handleClick the instant the component renders — not when the button is clicked. If a handler needs to run with specific arguments, wrap it in an inline arrow function instead: onClick={() => handleDelete(itemId)}. The arrow function itself is the thing passed to onClick; it just happens to call handleDelete only once actually clicked.
The Event Object
React automatically passes an event object as the handler's first argument, same as it would in plain JavaScript DOM event handling. event.target is the actual DOM element the event happened on — event.target.value is by far the most common thing read off it, giving the current text inside an input as the user types.
Handling Form Submission
event.preventDefault() stops the browser's default behavior for the event — for a form's onSubmit, that default is a full page reload, which would wipe out everything React has rendered. Calling it at the very start of the handler is the standard first line for almost every form submission handler you'll write.
Passing Extra Information to a Handler
Wrapping the call in an arrow function is also how a parent's function gets called with information only the child knows — here, id is a prop the child received, and onDelete is a function the parent passed down. The child doesn't need to know what onDelete does internally; it just calls it with the right ID when its own delete button is clicked. This "child calls a function the parent gave it" pattern is exactly how a child triggers a change in a parent's state, mentioned back in Chapter 2.
handle — handleClick, handleChange, handleSubmit — while the prop itself (when passed down as a callback, like onDelete above) is named starting with on. Following this consistently makes it easy to tell at a glance which functions are event handlers just by their name.
| Prop | Fires when... |
|---|---|
| onClick | An element is clicked |
| onChange | An input/textarea/select's value changes |
| onSubmit | A form is submitted (button click or Enter key) |
| onMouseEnter / onMouseLeave | The cursor enters/leaves an element |
| onKeyDown | A key is pressed while an element is focused |
Coding Challenges
Build a component with a text input and a paragraph below it. As the user types, the paragraph should update live to show exactly what's in the input, using onChange and useState together.
📄 View solutionBuild a form with a single text input and a submit button. On submit, prevent the default page reload and log the entered value to the console, then clear the input.
📄 View solutionBuild a ColorButton component that accepts a color prop and an onSelect callback prop, calling onSelect(color) when clicked. Render three of them in App, each logging which color was picked.
📄 View solutionChapter 4 Quick Reference
- Always pass a function reference to an event prop —
onClick={handleClick}, neveronClick={handleClick()} - Need to pass arguments? Wrap it:
onClick={() => handleDelete(id)} - React passes an event object automatically —
event.target.valuereads an input's current text - event.preventDefault() — stops a form's default full-page-reload submit behavior
- Naming convention: handlers are named
handleX, callback props are namedonX - A child calling a function prop is how it triggers a change up in its parent
- Next chapter: conditional rendering — showing different JSX based on state/props