Event handling in React lets your components respond to user actions such as clicks, typing, form submissions, and mouse or keyboard events. Instead of dealing directly with browser-specific events, React wraps them in Synthetic Events, giving you a consistent, cross-browser API.
In this topic, you’ll learn how to attach event handlers, pass arguments, work with the event object, prevent default browser behavior, and combine multiple events to build interactive components.
✨ Core idea: “React events are just props that receive functions.”
onClick, onChange, onSubmit.onclick="...").onClick={() => fn("value")}).event.preventDefault().In React, you attach event handlers as JSX attributes on elements. The attribute name is written in camelCase, and the value is a function reference:
// Basic pattern: pass a function reference to an event prop
function Example() {
function handleClick() {
alert("Clicked!");
}
return (
<button onClick={handleClick}>Click Me</button>
);
}
Notice that we pass handleClick, not handleClick(). Calling handleClick() directly would execute the function immediately when the component renders, instead of when the event (click) actually happens.
Here’s a simple button component that shows an alert when clicked. This demonstrates the most basic form of event handling in a React functional component.
// Handle a button click with a named handler function
function ClickButton() {
function handleClick() {
alert("Button clicked!");
}
return (
<button className="btn btn-primary" onClick={handleClick}>
Click Me
</button>
);
}
✅ Correct: onClick={handleClick}
❌ Incorrect: onClick={handleClick()} (this runs immediately during render).
To send custom data to an event handler (for example, a user’s name), wrap the call in an arrow function. The event handler itself can then receive that data as a parameter.
// Pass different names into the same click handler
function GreetUser() {
const sayHello = (name) => alert(`Hello, ${name}!`);
return (
<div>
<button
className="btn btn-success me-2"
onClick={() => sayHello("Ananya")}
>
Greet Ananya
</button>
<button
className="btn btn-secondary"
onClick={() => sayHello("Rahul")}
>
Greet Rahul
</button>
</div>
);
}
The arrow function (() => sayHello("Ananya")) is created on each render. In simple components this is fine, but for performance-sensitive parts of your app, you can memoize handlers using useCallback().
For inputs, React sends an event object to your handler automatically. This object is a SyntheticEvent, containing useful properties such as target.value for text inputs.
// Log every change the user types into the input field
function InputLogger() {
const handleChange = (e) => {
console.log("Input:", e.target.value);
};
return (
<input
type="text"
className="form-control w-50"
placeholder="Type something..."
onChange={handleChange}
/>
);
}
As the user types, the onChange handler fires on each keystroke, and you can read the latest value from e.target.value.
You can attach multiple event handlers in the same component to create richer interactions. A classic example is a counter with “+” and “–” buttons.
// Simple counter using click events on + and - buttons
function Counter() {
const [count, setCount] = React.useState(0);
const handleIncrement = () => setCount((c) => c + 1);
const handleDecrement = () => setCount((c) => c - 1);
return (
<div className="text-center">
<h4>Count: {count}</h4>
<button
className="btn btn-outline-primary me-2"
onClick={handleIncrement}
>
+
</button>
<button
className="btn btn-outline-danger"
onClick={handleDecrement}
>
-
</button>
</div>
);
}
Some elements, like forms and links, have default browser behavior. For example, a form submission normally reloads the page. To stop this and handle the logic yourself, call e.preventDefault() in the event handler.
// Prevent the form from reloading the page on submit
function FormExample() {
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="Your name"
/>
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
);
}
This pattern is very common in React: prevent the default behavior, then perform your own actions such as validation, API calls, or updating component state.
Try combining these patterns in a small demo app: a form that logs the input, validates it, and then updates a counter or shows a custom message on submit.
onClick, not onclick).this context.useCallback() to avoid unnecessary re-creations.preventDefault() to stop unwanted browser behavior on forms and links when you want full control in React.onMouseEnter and onMouseLeave.onKeyDown.Goal: Understand how to handle user events in React, pass arguments to handlers, and use the event object effectively to control interactivity.