Events

Course 1 · Ch 4
Event Handling
Responding to clicks, typing, and form submissions — the bridge between user actions and state changes

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

function Greeting() { // inline — fine for short one-liners return <button onClick={() => alert("Hi!")}>Say hi</button>; } function SaveButton() { // named — better once there's real logic function handleClick() { console.log("Saving..."); } return <button onClick={handleClick}>Save</button>; }

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.

The classic mistake: calling the function instead of passing it
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

function SearchBox() { function handleChange(event) { console.log(event.target.value); } return <input onChange={handleChange} />; }

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

function SignupForm() { function handleSubmit(event) { event.preventDefault(); console.log("Form submitted"); } return ( <form onSubmit={handleSubmit}> <input type="email" /> <button type="submit">Sign up</button> </form> ); }

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

function TodoItem({ id, text, onDelete }) { return ( <li> {text} <button onClick={() => onDelete(id)}>Delete</button> </li> ); }

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.

Naming convention: handleX
Most React code names event handler functions starting with handlehandleClick, 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.
PropFires when...
onClickAn element is clicked
onChangeAn input/textarea/select's value changes
onSubmitA form is submitted (button click or Enter key)
onMouseEnter / onMouseLeaveThe cursor enters/leaves an element
onKeyDownA key is pressed while an element is focused

Coding Challenges

Challenge 1

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 solution
Challenge 2

Build 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 solution
Challenge 3

Build 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 solution

Chapter 4 Quick Reference

  • Always pass a function reference to an event prop — onClick={handleClick}, never onClick={handleClick()}
  • Need to pass arguments? Wrap it: onClick={() => handleDelete(id)}
  • React passes an event object automatically — event.target.value reads 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 named onX
  • 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