React events are attached using camelCase attribute names, like onClick or onChange, and are passed a function reference rather than a string of code, unlike the old-style HTML onclick="..." attribute. Under the hood, React attaches a single listener at the root of the application and uses event delegation, along with its own SyntheticEvent wrapper around the browser's native event, which normalizes behavior consistently across different browsers while still exposing the same familiar event properties and methods, like .preventDefault().
1Understanding Events
React events are attached using camelCase attribute names, like onClick or onChange, and are passed a function reference rather than a string of code, unlike the old-style HTML onclick="..." attribute. Under the hood, React attaches a single listener at the root of the application and uses event delegation, along with its own SyntheticEvent wrapper around the browser's native event, which normalizes behavior consistently across different browsers while still exposing the same familiar event properties and methods, like .preventDefault().
Pass a function reference, onClick={handleClick}, not a function call, onClick={handleClick()} — the latter calls the function immediately during rendering, rather than only when the button is actually clicked.
function Button() {
const handleClick = () => console.log('Button clicked!');
return <button onClick={handleClick}>Click me</button>;
}2Practical Example
Here is a real-world application of Events showing how it is used in production React code.
function ItemButton({ id }) {
const handleClick = (itemId) => console.log('Clicked item:', itemId);
return <button onClick={() => handleClick(id)}>Select</button>;
}
// <ItemButton id={42} />3Best Practices
Follow these guidelines when working with Events:
1. Pass event handlers as function references, never invoking them directly in JSX, to avoid accidentally calling the handler during every render
2. Use an inline arrow function, onClick={() => handleClick(id)}, when you need to pass arguments to the handler, since a direct reference alone can't include extra arguments
3. Call event.preventDefault() on a form's submit event to stop the browser's default full-page reload before handling the submission with your own JavaScript logic
Tip: Pass a function reference, onClick={handleClick}, not a function call, onClick={handleClick()} — the latter calls the function immediately during rendering, rather than only when the button is actually clicked.
function Button() {
const handleClick = () => console.log('Button clicked!');
return <button onClick={handleClick}>Click me</button>;
}4Stopping Propagation
Because React uses event delegation, a click on a nested element also triggers any click handlers on its parents, in order — the same bubbling behavior as native DOM events. Calling event.stopPropagation() inside a handler prevents the event from continuing to bubble up and firing those parent handlers.
function Card({ onCardClick, onDeleteClick }) {
return (
<div onClick={onCardClick}>
<button onClick={(e) => { e.stopPropagation(); onDeleteClick(); }}>Delete</button>
</div>
);
}