React’s event system lets components respond to user actions like clicks, typing, form submissions, and key presses, using a cross-browser wrapper called SyntheticEvent.
You can handle events in both function components (with hooks) and class components (with methods and bindings).
onClick, onChange, onSubmit.this.e or event, is a SyntheticEvent.e.preventDefault() to stop form submission, link navigation, etc.e.stopPropagation() to stop bubbling.Function component event handler (typical pattern)
In function components, you define an event handler and pass the function reference to a JSX attribute:
onClick={handleClick} ✅ — passes the function itself.onClick={handleClick()} ❌ — calls the function immediately during render.Class component event handler (two main options)
this.methodName = this.methodName.bind(this).handleClick = () => {...} (modern style).Event object
React passes a SyntheticEvent object to handlers, which normalizes behaviour across browsers and exposes properties like target, type, currentTarget, etc.
A basic click handler in a function component:
// Simple click handler in a function component
function ButtonClick() {
const handleClick = () => {
alert("You clicked the button!");
};
return (
<button className="btn btn-primary" onClick={handleClick}>
Click Me
</button>
);
}
Here, onClick={handleClick} is a function reference. The function runs only when the button is clicked.
The first argument to the handler is a SyntheticEvent. You can read values from e.target:
// Reading input value using the event object
function InputHandler() {
const handleChange = (e) => {
console.log("Typed:", e.target.value);
};
return (
<input
type="text"
className="form-control w-50"
placeholder="Type something..."
onChange={handleChange}
/>
);
}
Every time the user types, React calls handleChange with a fresh SyntheticEvent, whose target.value holds the current input text.
In class components, handlers are methods that must be bound to the component instance so that this works correctly.
// Class component using constructor binding
class Clicker extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<button className="btn btn-success" onClick={this.handleClick}>
Count: {this.state.count}
</button>
);
}
}
// Class component using an arrow-function handler
class ArrowClicker extends React.Component {
state = { clicks: 0 };
handleClick = () => {
this.setState({ clicks: this.state.clicks + 1 });
};
render() {
return (
<button className="btn btn-warning" onClick={this.handleClick}>
Clicked: {this.state.clicks}
</button>
);
}
}
To pass extra data to a handler, wrap the call in an arrow function so that it runs only when the event fires:
// Passing extra data to an event handler
function GreetUser() {
const greet = (name) => alert(`Hello, ${name}!`);
return (
<div>
<button className="btn btn-info me-2" onClick={() => greet("Ananya")}>
Greet Ananya
</button>
<button className="btn btn-secondary" onClick={() => greet("Rahul")}>
Greet Rahul
</button>
</div>
);
}
Forms try to submit and reload the page by default. Use e.preventDefault() to stop that and handle the data in JavaScript instead:
// Preventing default form submission
function FormSubmit() {
const handleSubmit = (e) => {
e.preventDefault();
alert("Form Submitted!");
};
return (
<form onSubmit={handleSubmit} className="p-3 border rounded shadow-sm w-50">
<input className="form-control mb-2" placeholder="Enter your name" />
<button className="btn btn-primary" type="submit">Submit</button>
</form>
);
}
Events bubble from child to parent. If you want to stop a click from reaching a parent, call e.stopPropagation():
// Stopping an event from bubbling to the parent
function PropagationExample() {
const parentClick = () => alert("Parent clicked!");
const childClick = (e) => {
e.stopPropagation();
alert("Child clicked!");
};
return (
<div className="p-3 border" onClick={parentClick}>
Parent
<button className="btn btn-danger ms-2" onClick={childClick}>
Child Button
</button>
</div>
);
}
"You clicked the button!".Typed: <current text> to the console."Parent clicked!"."Child clicked!" because stopPropagation() prevents the parent handler from running.onKeyDown / onKeyUp.onClick={handleClick}).SyntheticEvent; if you need it asynchronously, call e.persist().preventDefault() and stopPropagation() intentionally to control browser behaviour and bubbling.handleClick, handleSubmit, handleChange, for readability.useState.this.setState.e.preventDefault(), andonClick handler.e.stopPropagation() in its handler.console.log(e) and inspect:
e.target vs e.currentTargete.type and other useful properties.Goal: Master event handling in both functional and class components, including how to bind methods, use arrow functions, access event objects, and control default behaviour and propagation.