beginner17 min

Handling Events in React

How a click becomes a function call: passing handler functions as props, and the difference between calling a function and passing a reference to one.

What you'll learn

  • Explain how a JSX event prop connects to a handler function
  • Identify the difference between passing a function reference and accidentally calling it during render
  • Pass data from an event handler back up to a parent via a callback prop

Prerequisites

Explanation

<button onClick={handleClick}> is, underneath the JSX, exactly what you'd expect from the previous lessons: a prop named onClick whose value is a function. React attaches its own event system and calls that function when the button is actually clicked. There's no special magic beyond "a prop that happens to hold a function, which gets called later."

That framing explains the single most common beginner mistake in this area: onClick={handleClick} passes a reference to the function — onClick={handleClick()} calls it immediately, during render, and passes whatever it returns (often undefined) as the prop instead. The parentheses are the entire difference between "call this later, when clicked" and "call this right now, while rendering." A component that appears to do nothing when clicked, but does something weird immediately on every render, almost always has this exact bug.

When a handler needs to pass along extra information — which course was clicked, which item in a list — you wrap it in an inline arrow function: onClick={() => handleSelect(course.id)}. That outer arrow function is the reference passed to onClick; it just happens to call handleSelect with a specific argument when it eventually runs.

This is also the concrete mechanism behind "a child communicates up to its parent," introduced in the props lesson: the parent defines a handler function and passes it down as a prop (onSelect); the child attaches it (or a wrapper around it) to a real DOM event like onClick; when the user interacts, the child calls that function, optionally passing along data specific to what happened. The data still only ever moved down as a function reference — it's the timing of the call, triggered by the user's action, that makes it feel like information flowing upward.

Example

Modeling the difference between passing a function reference and calling it immediately — the single most common event-handler bug.

function handleClick() {
  return "clicked!";
}

// Correct: pass the reference. React calls it later, on click.
const correctProp = handleClick;
console.log(typeof correctProp); // "function" -- ready to be called later

// Buggy: calling it immediately assigns its RETURN VALUE as the prop.
const buggyProp = handleClick();
console.log(typeof buggyProp); // "string" -- already ran, nothing left to call on click

Try it yourself

Fix the buggy line below (remove the parentheses) and re-run to see the type change.

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Guided exercise

Guided exercise

A list needs each button's handler to know which item it belongs to. Write makeClickHandler(itemId, onSelect) that returns a new function taking no arguments, which calls onSelect(itemId) when invoked -- modeling the `() => handleSelect(item.id)` inline-arrow pattern.

Checks: returns a function, doesn't call onSelect immediately · onSelect not called before the handler runs · calling the returned handler calls onSelect with the right id

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Independent exercise

Independent exercise

Write a function isLikelyCalledDuringRender(propValue) that returns true if propValue is NOT a function (suggesting someone wrote onClick={handleClick()} instead of onClick={handleClick}), false if it IS a function (correctly passed as a reference).

Checks: does not flag a real function · flags a string value · flags an undefined value

Code editor. Press Escape then Tab to leave the editor if keyboard focus becomes trapped. Press Control+Shift+M inside the editor to toggle Tab-key focus trapping.

Loading editor…

Stuck? Get a hint.

Common mistakes

  • Writing `onClick={handleClick()}` instead of `onClick={handleClick}`, accidentally calling the handler during render instead of passing it as a reference.
  • Forgetting to wrap a parameterized call in an inline arrow function, e.g. writing `onClick={handleSelect(item.id)}` instead of `onClick={() => handleSelect(item.id)}`.
  • Assuming a child can somehow read a value back out of a parent without the parent explicitly passing a callback prop down.

Knowledge check

Knowledge check

1. What is the difference between `onClick={handleClick}` and `onClick={handleClick()}`?
2. Why is `onClick={() => handleSelect(item.id)}` used instead of `onClick={handleSelect}` when extra data is needed?
3. How does a child component's event ultimately let a parent "know" something happened?

Takeaway

Event props hold function references, called later by React when the event actually happens — calling a handler immediately (missing the parentheses distinction) is the most common beginner event bug.

Summary

This lesson covered how JSX event props connect to handler functions, the reference-vs-call distinction that causes most handler bugs, and passing data up via callback props triggered by real events.

References

Your notes

Notes save automatically.

Finished this lesson?

Mark it complete to track your progress and schedule a future review.