🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
REFERENCEreact

react Documentation

LOADING ENGINE...

Custom Events

AI & DATA SCIENCE // custom-events

React doesn't have a built-in custom-event system like the DOM's CustomEvent — components instead communicate custom 'events' by passing callback functions down as props.

Syntax

<ChildComponent onCustomAction={handleCustomAction} />

Deep Dive Course

Since React components communicate through props rather than a dedicated event-emitter mechanism, the standard way for a child component to notify its parent that something happened, its own version of a custom event, is for the parent to pass a callback function down as a prop, which the child then simply calls whenever the relevant action occurs, optionally passing along any relevant data as arguments. This callback-prop pattern is React's idiomatic equivalent of a custom event: instead of the child dispatching an event that bubbles upward, it directly invokes a function reference the parent already handed it.

1Understanding Custom Events

Since React components communicate through props rather than a dedicated event-emitter mechanism, the standard way for a child component to notify its parent that something happened, its own version of a custom event, is for the parent to pass a callback function down as a prop, which the child then simply calls whenever the relevant action occurs, optionally passing along any relevant data as arguments. This callback-prop pattern is React's idiomatic equivalent of a custom event: instead of the child dispatching an event that bubbles upward, it directly invokes a function reference the parent already handed it.

💡

There's no need to reach for the browser's native CustomEvent and dispatchEvent APIs inside a React component tree — passing and calling a callback prop achieves the exact same notify-the-parent goal in a way that fits React's normal data flow.

editor.html
function Child({ onCustomAction }) {
  return <button onClick={() => onCustomAction('some data')}>Trigger</button>;
}

function Parent() {
  const handleCustomAction = (data) => console.log('Custom action fired with:', data);
  return <Child onCustomAction={handleCustomAction} />;
}
localhost:3000

2Practical Example

Here is a real-world application of Custom Events showing how it is used in production React code.

editor.html
function RatingStars({ onRatingChanged }) {
  return (
    <div>
      {[1, 2, 3, 4, 5].map(star => (
        <span key={star} onClick={() => onRatingChanged(star)}>★</span>
      ))}
    </div>
  );
}

// <RatingStars onRatingChanged={(rating) => console.log('New rating:', rating)} />
localhost:3000

3Best Practices

Follow these guidelines when working with Custom Events:

1. Pass a callback function as a prop from parent to child whenever the child needs to notify the parent about something, rather than reaching for the native CustomEvent API

2. Name callback props starting with 'on', like onItemSelected or onCustomAction, mirroring the convention used by React's own built-in event props

3. Pass any relevant data about what happened as arguments to the callback function when the child calls it, rather than requiring the parent to look the information up separately

⚠️

Tip: There's no need to reach for the browser's native CustomEvent and dispatchEvent APIs inside a React component tree — passing and calling a callback prop achieves the exact same notify-the-parent goal in a way that fits React's normal data flow.

editor.html
function Child({ onCustomAction }) {
  return <button onClick={() => onCustomAction('some data')}>Trigger</button>;
}

function Parent() {
  const handleCustomAction = (data) => console.log('Custom action fired with:', data);
  return <Child onCustomAction={handleCustomAction} />;
}
localhost:3000

Examples

Example 01Basic Usage
function Child({ onCustomAction }) {
  return <button onClick={() => onCustomAction('some data')}>Trigger</button>;
}

function Parent() {
  const handleCustomAction = (data) => console.log('Custom action fired with:', data);
  return <Child onCustomAction={handleCustomAction} />;
}
Example 02Advanced Example
function RatingStars({ onRatingChanged }) {
  return (
    <div>
      {[1, 2, 3, 4, 5].map(star => (
        <span key={star} onClick={() => onRatingChanged(star)}>★</span>
      ))}
    </div>
  );
}

// <RatingStars onRatingChanged={(rating) => console.log('New rating:', rating)} />

Best Practices

  • Pass a callback function as a prop from parent to child whenever the child needs to notify the parent about something, rather than reaching for the native CustomEvent API
  • Name callback props starting with 'on', like onItemSelected or onCustomAction, mirroring the convention used by React's own built-in event props
  • Pass any relevant data about what happened as arguments to the callback function when the child calls it, rather than requiring the parent to look the information up separately

Interview Question

Why does React favor passing callback functions as props over using the DOM's native CustomEvent and dispatchEvent APIs for component-to-component communication?

Hint: Think about how React's whole data-flow model is already structured, and whether introducing a separate, DOM-based event system fits naturally into that or works against it.

React's entire data-flow model is built around explicit, traceable connections between components: data flows down through props, and a callback prop passed down and then called by a child is really just that same explicit, one-directional flow used in the other direction, letting you follow exactly which parent handed which function to which child by simply reading the code. The DOM's native CustomEvent system, by contrast, is built around implicit, ambient dispatching and bubbling through the actual DOM tree, which sits somewhat outside React's own component-based data model and virtual DOM abstraction, making the connection between an event being dispatched somewhere and a handler eventually catching it much harder to trace directly from the component code alone. Sticking to callback props keeps a component's communication pattern consistent with, and just as easy to trace as, its regular props-based data flow, rather than introducing a second, separate communication mechanism that works fundamentally differently.

Exercises

MediumPractice using Custom Events in a real scenario.
View Solution
function Child({ onCustomAction }) {
  return <button onClick={() => onCustomAction('some data')}>Trigger</button>;
}

function Parent() {
  const handleCustomAction = (data) => console.log('Custom action fired with:', data);
  return <Child onCustomAction={handleCustomAction} />;
}

Frequently Asked Questions

Why does React favor passing callback functions as props over using the DOM's native CustomEvent and dispatchEvent APIs for component-to-component communication?

React's entire data-flow model is built around explicit, traceable connections between components: data flows down through props, and a callback prop passed down and then called by a child is really just that same explicit, one-directional flow used in the other direction, letting you follow exactly which parent handed which function to which child by simply reading the code. The DOM's native CustomEvent system, by contrast, is built around implicit, ambient dispatching and bubbling through the actual DOM tree, which sits somewhat outside React's own component-based data model and virtual DOM abstraction, making the connection between an event being dispatched somewhere and a handler eventually catching it much harder to trace directly from the component code alone. Sticking to callback props keeps a component's communication pattern consistent with, and just as easy to trace as, its regular props-based data flow, rather than introducing a second, separate communication mechanism that works fundamentally differently.

Related Functions

events-in-reactonclickcomponent-rendering