Fundamentals
Events
Master React event handling, covering SyntheticEvents, inline argument passing, preventDefault, and event delegation mechanics.
1. Learning Objectives
In this lesson, you will learn how to capture and respond to user interactions in React. By the end of this topic, you will be able to:
- Attach event handlers to JSX tags using camelCase naming.
- Explain the purpose of React's cross-browser
SyntheticEventwrapper. - Pass custom arguments to event handlers using arrow functions.
- Control event flows using
preventDefault()andstopPropagation(). - Understand how React optimizes performance using event delegation.
2. Overview
Event handling in React is similar to handling events on standard HTML elements, with two main differences: event names are camelCase (e.g. onClick instead of onclick), and event handlers are passed as JavaScript function references instead of strings. To ensure cross-browser consistency, React wraps native browser events in a normalized object called a SyntheticEvent.
3. Why This Topic Matters
Handling events efficiently is key to building responsive, interactive applications:
- Cross-Browser Support: Different browsers implement event properties differently. React's SyntheticEvents normalize these differences, ensuring your event logic behaves consistently on all platforms.
- Performance Optimization: Attaching individual event listeners to thousands of DOM elements is resource-intensive. React uses a single event listener at the root of the application (event delegation) to handle all events efficiently.
4. Real-World Analogy
Think of React event handling like **an office building receptionist**:
- Individual Security Guards (Vanilla DOM): Stationing a security guard at the door of every single office inside the building to handle visitors. This requires a lot of guards (listeners) and is difficult to coordinate.
- The Receptionist (React Event Delegation): Stationing a single receptionist at the main entrance of the building. When a visitor arrives (an event occurs), the receptionist checks their badge, determines which office they want to visit, and calls that office's handler. React uses this centralized delegation model to manage events efficiently.
5. Core Concepts
Below is a comparison of event handling in vanilla HTML and React:
| Feature | Vanilla HTML Standards | React Standards |
|---|---|---|
| Naming Convention | Lowercase (e.g. onclick, onsubmit). |
camelCase (e.g. onClick, onSubmit). |
| Handler Reference | Passed as a string (e.g. "handleClick()"). |
Passed as a function reference (e.g. {handleClick}). |
| Default Prevention | Can return false inside inline attributes. |
Must call event.preventDefault() explicitly. |
| Event Object Type | Native Browser Event. | React SyntheticEvent wrapper. |
6. Syntax & API Reference
This example shows how to declare event handlers and pass arguments:
7. Visual Diagram
This diagram displays how click events bubble up to the root container where React's event delegator handles them:
8. Live Example — Full Working Code
Below is a complete HTML page demonstrating submission prevention and inline click handlers:
What just happened? Clicking "Submit Form" triggers handleSubmit. The event.preventDefault() call prevents the browser from reloading the page, allowing us to handle the form submission in JavaScript. The "Save" and "Cancel" buttons use arrow functions to pass arguments (e.g. `'Save'`) to the click handler.
9. Interactive Playground
Try It Yourself Challenges:
- Add a new button named "Clear" that calls
setStatusMsg('Ready')on click. - Add an
onChangelistener to a text input field, displaying the user's input in the status message in real-time.
10. Common Mistakes
| Mistake | Why it happens | Wrong | Correct |
|---|---|---|---|
| Executing handler during render instead of referencing it | Adding parenthesis to an event handler (e.g. onClick={{{handleClick()}}}) executes the function immediately during rendering, rather than waiting for a click event. |
onClick={handleClick()} |
onClick={handleClick} (no parenthesis) |
| Mutating event objects inside asynchronous calls | React uses event pooling in older versions. The SyntheticEvent object is recycled, so its properties become null after the handler executes. |
setTimeout(() => console.log(event.target), 100); |
Copy properties to local variables first: const val = event.target; setTimeout(() => console.log(val), 100); |
11. Best Practices
- Pass function references: Pass the function reference directly (`onClick={handleClick}`) rather than calling it (`onClick={handleClick()}`).
- Use arrow functions to pass arguments: Wrap the handler call in an arrow function (e.g. `onClick={() => handleDelete(id)}`) to pass parameters safely.
- Call preventDefault() explicitly: Do not return `false` to prevent default browser behavior. Always call `event.preventDefault()` explicitly.
12. Browser Compatibility/Requirements
SyntheticEvent supports all standard event specifications (W3C standard properties).
13. Interview Questions
Q1: What is a `SyntheticEvent` in React, and why is it used?
Answer: A SyntheticEvent is a cross-browser wrapper around native browser events. It normalizes event properties so they work consistently across different browsers. It has the same interface as native events (like `stopPropagation` and `preventDefault`), but resolves cross-browser incompatibilities automatically.
Q2: How does event delegation work in React?
Answer: React does not attach event listeners to individual DOM elements. Instead, it attaches a single listener to the root container node (e.g. `#root`). When an event occurs, it bubbles up to this root container, where React captures it and maps it to the correct component handler. This improves performance and memory usage.
14. Debugging Exercise
Identify the bug in this list card that causes items to trigger details popups when the Delete button is clicked:
Diagnosis: The click event on the Delete button bubbles up to its parent `div` wrapper, triggering the `onShowDetails` handler immediately after the delete handler runs.
Fix: Call event.stopPropagation() inside the Delete button's handler to prevent the event from bubbling up to the parent element:
15. Practice Exercises
Exercise 1: Create a drag-and-drop file upload zone
Build a component named DropZone. Attach event listeners for onDragOver and onDrop. Call preventDefault() to prevent the browser from opening dropped files in a new tab.
16. Scenario-Based Challenge
The Dynamic Search Overlay Close Button:
You are designing a search overlay window. Clicking anywhere outside the search window should close the overlay, but clicking inside the search window should not. Describe how you would attach window click listeners and manage event bubbling to implement this behavior.
17. Quick Quiz
Q1: Which event method is called to prevent form submissions from reloading the page?
A) event.stopPropagation()
B) event.preventDefault()
C) event.cancelBubble()
Answer: B — event.preventDefault() prevents default browser behaviors, like form submissions reloading the page.
18. Summary & Key Takeaways
- React uses camelCase names for event handlers inside JSX templates.
- React wraps native browser events in a normalized, cross-browser
SyntheticEventobject. - React uses event delegation at the root container to manage events efficiently.
- Use
event.preventDefault()andevent.stopPropagation()to manage event flows.
19. Cheat Sheet
| Event Method | Purpose |
|---|---|
event.preventDefault() |
Prevents default browser actions (like page reloads on form submissions). |
event.stopPropagation() |
Stops event bubbling, preventing parent click handlers from running. |
onClick={() => handler(id)} |
Passes arguments to event handlers on click. |