What are Synthetic Events in React?
This article provides a clear and concise overview of Synthetic Events in React, explaining what they are, why React uses them, and how they differ from native browser events. You will learn about the benefits of React’s event-handling system, including cross-browser compatibility and performance optimization, as well as how to work with them in your code.
Understanding Synthetic Events
A Synthetic Event is a cross-browser wrapper around the browser’s
native event. It has the same interface as the browser’s native event,
including methods like preventDefault() and
stopPropagation(), but it is designed to behave identically
across all modern browsers.
When you write an event handler in React, such as
onClick or onChange, the event object passed
to your function is not a native browser event. Instead, it is an
instance of SyntheticEvent.
Why React Uses Synthetic Events
React implements this wrapper system for two primary reasons:
1. Cross-Browser Consistency
Different browsers historically handle events in slightly different ways, using different property names or behaviors. React’s Synthetic Events normalize these differences so that your event-handling code works seamlessly across Chrome, Firefox, Safari, Edge, and older browsers without requiring browser-specific workarounds.
2. Performance Optimization (Event Delegation)
Instead of attaching individual event listeners to every DOM node that needs one, React attaches a single event listener to the root of your document (or the root of the React tree in React 17+).
When an event fires in the browser, it bubbles up to this root
listener. React then maps the native event to the appropriate
SyntheticEvent and dispatches it to the correct React
component. This process is called event delegation, and
it drastically reduces memory consumption and improves application
performance.
Key Differences Between Synthetic and Native Events
While Synthetic Events mimic native events, there are a few key differences to keep in mind:
Naming Conventions: React event names are written in camelCase (e.g.,
onClick,onSubmit,onKeyDown) rather than lowercase (e.g.,onclick,onsubmit,onkeydown).Passing Functions: In React, you pass a JavaScript function as the event handler rather than a string.
// HTML (Native) <button onclick="handleClick()">Click Me</button> // React (Synthetic) <button onClick={handleClick}>Click Me</button>Preventing Default Behavior: In React, you cannot return
falseto prevent default behavior. You must explicitly callevent.preventDefault().
Accessing the Native Event
If you ever need to access the underlying browser event for a
specific API that React does not wrap, you can do so using the
nativeEvent attribute:
const handleClick = (event) => {
console.log(event); // This is the SyntheticEvent
console.log(event.nativeEvent); // This is the actual native browser PointerEvent/MouseEvent
};Note on Event Pooling (React 16 vs. React 17+)
In React 16 and earlier, React used a technique called Event
Pooling to improve performance. Synthetic event objects were
reused, and their properties were nullified immediately after the event
callback ran. To access event properties asynchronously (e.g., inside a
setTimeout), you had to call
event.persist().
In React 17 and later, event pooling has been
removed. You can now access event properties asynchronously
without needing to call event.persist().