Event Handling
Overview
Static UIs are useless. A web application must respond to user interactions: clicks, hovers, form submissions, and keystrokes. In traditional Vanilla JavaScript, you handle this by querying the DOM for an element and attaching an addEventListener to it.
React dramatically simplifies this by allowing you to attach event handlers directly inline within the JSX element itself. React event handlers are passed as props, and they strictly follow camelCase naming conventions (e.g., onClick instead of HTML's lowercase onclick).
Crucially, instead of passing a string of JavaScript code to execute (like old-school HTML), you pass the actual JavaScript function reference. When the user interacts with the element, React invokes the function you provided, giving you the power to trigger state changes, validate inputs, or send data to a server.
Syntax
function EventDemo() {
// 1. A defined function reference (Recommended for complex logic)
const handleFormSubmit = (event) => {
event.preventDefault();
alert("Form Submitted!");
};
return (
<form onSubmit={handleFormSubmit}>
{/* 2. An inline arrow function (Great for simple, one-line logic) */}
<button type="button" onClick={() => alert("Button Clicked!")}>
Test Button
</button>
<button type="submit">Submit Form</button>
</form>
);
}Common Pitfalls
- Calling the function instead of passing it: Writing
<button onClick={handleClick()}>is a massive mistake. The parentheses()immediately invoke the function the moment the component renders, before the user ever clicks. The function will likely returnundefined, meaning nothing happens when you actually click the button. You must pass the reference:onClick={handleClick}. - Passing arguments incorrectly: If you need to pass an ID to a handler, you cannot write
onClick={deleteItem(id)}(immediate invocation). You must wrap it in an inline arrow function:onClick={() => deleteItem(id)}.
Interview Questions
Because JSX is compiled into JavaScript, and React event handlers are actually properties on a JavaScript object (the props object). JavaScript heavily favors camelCase for object properties and variables, so React adopted this to maintain consistency with the language.
By default, HTML forms trigger a full page refresh when submitted, which destroys the React Single Page Application state. You must accept the event object in your handler and call event.preventDefault() as the very first line of your function.
Real-World Example
Passing Arguments to Handlers: When mapping over arrays, you almost always need to pass the specific item's ID to the event handler so your code knows which item to delete, update, or select.
function ShoppingCart({ items }) {
// A generic handler that accepts an ID
const handleRemove = (productId) => {
console.log(`Removing product ${productId} from database...`);
// API call logic goes here
};
return (
<ul>
{items.map(item => (
<li key={item.id}>
{item.name}
{/* We MUST use an arrow function here to pass the specific item.id */}
<button onClick={() => handleRemove(item.id)}>
Remove
</button>
</li>
))}
</ul>
);
}Check Your Knowledge
Test your understanding of Event Handling with these quick questions.