CodeOath
← All posts
React75 min total · 17 parts

React Fundamentals: Components, Hooks, and the Virtual DOM

Contents — Part 6 of 17: Handling Events
Part 6 of 17 · ~1 min

Handling Events

React wraps native DOM events in a cross-browser wrapper (historically called SyntheticEvent), attached via camelCase props:

function Button() {
  function handleClick(e) {
    e.preventDefault();
    console.log("clicked");
  }
  return <button onClick={handleClick}>Click me</button>;
}

Passing arguments to a handler needs a wrapping arrow function, since JSX event props expect a function reference, not a function call:

// Wrong — calls deleteItem(id) immediately during render, not on click
<button onClick={deleteItem(id)}>Delete</button>

// Right — passes a new function that calls deleteItem(id) when clicked
<button onClick={() => deleteItem(id)}>Delete</button>

Under the hood, React historically attaches most event listeners once at the root of the app and uses event delegation/bubbling to figure out which component's handler should fire, rather than attaching a real native listener to every single DOM node — an implementation detail that mostly doesn't matter to app code, except that it's why calling e.stopPropagation() inside a React handler stops other React handlers from firing predictably, following the same bubble order as the JSX tree.