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.
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} />;
}2Practical Example
Here is a real-world application of Custom Events showing how it is used in production React code.
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)} />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.
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} />;
}