Skip to content

Events in React

React wraps browser events in synthetic events for consistent cross-browser behavior. You attach handlers via camelCase props like onClick and onChange. This lesson covers patterns for interactive UIs.

Synthetic Events

React's SyntheticEvent wraps the native event. Handlers receive this wrapper, which behaves like the native event for common cases (preventDefault, stopPropagation, target).

In React 17+, events delegate to the root React container, not document, which improves compatibility with multiple React versions on one page.

function SearchBox() {
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Search submitted');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="search" onChange={(e) => setQuery(e.target.value)} />
      <button type="submit">Search</button>
    </form>
  );
}

Call preventDefault() on form submit to avoid a full page reload in SPAs.

Event Handler Patterns

// Inline arrow
<button onClick={() => deleteItem(id)}>Delete</button>

// Stable reference (better for memoized children)
<button onClick={handleDelete}>Delete</button>

// Pass event explicitly
<input onChange={handleChange} />
  • Pass a function reference, not a function call: onClick={fn} not onClick={fn()}.
  • Inline arrows are fine unless they break memoization in hot paths.
  • Use onKeyDown for keyboard interactions; prefer semantic elements.
  • React pools synthetic events in older versions — avoid async access without e.persist() (rare in modern React).

Common React Events

Frequently used DOM event props in React.

Prop Native Equivalent
onClick click
onChange change (inputs)
onSubmit submit
onKeyDown keydown
onFocus / onBlur focus / blur
onMouseEnter mouseenter

Passing Parameters to Handlers

Wrap handlers in arrows to pass arguments without invoking immediately.

items.map(item => (
  <button key={item.id} onClick={() => handleSelect(item.id)}>
    {item.name}
  </button>
));

Alternative: data attributes on the element and read from e.currentTarget.dataset.

Events and Accessibility

Click handlers on non-interactive elements (div, span) hurt accessibility. Use <button> for actions and <a href> for navigation. If you must use a div, add role, tabIndex, and keyboard handlers.

Common Mistakes

  • Calling the handler during render: onClick={handleClick()}.
  • Forgetting preventDefault on forms in SPAs.
  • Using only onClick on divs without keyboard support.
  • Creating new inline functions on every render in performance-critical lists without need.

Key Takeaways

  • React uses camelCase synthetic event props.
  • Pass function references to event props.
  • Use preventDefault and stopPropagation when needed.
  • Prefer semantic interactive elements for accessibility.

Pro Tip

Extract repeated inline handlers to named functions when the same list re-renders hundreds of items and profiling shows a cost.