Every event handler in React receives a SyntheticEvent instance rather than the browser's raw native event directly, which normalizes properties and methods, like .target, .preventDefault(), and .stopPropagation(), to behave identically across different browsers, insulating your code from the various cross-browser inconsistencies that existed in native event handling historically. If genuinely necessary, the original native browser event is still accessible via the SyntheticEvent's .nativeEvent property, though this is rarely needed in typical application code.
1Understanding Synthetic Events
Every event handler in React receives a SyntheticEvent instance rather than the browser's raw native event directly, which normalizes properties and methods, like .target, .preventDefault(), and .stopPropagation(), to behave identically across different browsers, insulating your code from the various cross-browser inconsistencies that existed in native event handling historically. If genuinely necessary, the original native browser event is still accessible via the SyntheticEvent's .nativeEvent property, though this is rarely needed in typical application code.
You almost never need to reach for event.nativeEvent — the SyntheticEvent object already exposes the same standard properties and methods you'd expect, normalized consistently across browsers, for the vast majority of use cases.
function Input() {
const handleChange = (event) => {
console.log(event.constructor.name);
console.log('Value:', event.target.value);
};
return <input onChange={handleChange} />;
}2Practical Example
Here is a real-world application of Synthetic Events showing how it is used in production React code.
function Link() {
const handleClick = (event) => {
console.log('Native event available:', event.nativeEvent instanceof MouseEvent);
};
return <a href="#" onClick={handleClick}>Click</a>;
}3Best Practices
Follow these guidelines when working with Synthetic Events:
1. Use the SyntheticEvent's normalized properties and methods, like .target and .preventDefault(), for everyday event handling rather than reaching for the native event directly
2. Access event.nativeEvent only for the rare cases needing a browser-specific native event property that SyntheticEvent doesn't expose
3. Read any needed event properties synchronously inside the handler itself, rather than storing the whole event object to inspect asynchronously later, since older React versions pooled and reused event objects
Tip: You almost never need to reach for event.nativeEvent — the SyntheticEvent object already exposes the same standard properties and methods you'd expect, normalized consistently across browsers, for the vast majority of use cases.
function Input() {
const handleChange = (event) => {
console.log(event.constructor.name);
console.log('Value:', event.target.value);
};
return <input onChange={handleChange} />;
}