Event Handling
Learn how React handles DOM events with camelCase handlers, function references, the synthetic event object, and preventDefault.
Introduction
Almost every interactive UI needs to respond to something the user does — a click, a keystroke, a form submission. In plain HTML and JavaScript, you would normally attach these behaviors with addEventListener or inline attributes like onclick. React has its own consistent way of wiring up events directly inside JSX.
In this lesson you will learn how React event handlers are named and written, the crucial difference between passing a function and calling one, how to pass extra arguments to a handler, what the synthetic event object gives you, and how to stop a form from reloading the page with event.preventDefault().
- How React event props differ from plain HTML attributes.
- Why you pass a function reference instead of calling the function.
- How to pass custom arguments to an event handler.
- What the synthetic event object is and how to read event.target.value.
- How to stop default browser behavior with event.preventDefault().
Events in React vs HTML
In HTML, event attributes are lowercase and take a string of JavaScript code, like onclick="doSomething()". In React, event props are written in camelCase — onClick, onChange, onSubmit — and you pass them an actual JavaScript function, not a string.
Plain HTML
- <button onclick="handleClick()">
- Click Me
- </button>
React JSX
- <button onClick={handleClick}>
- Click Me
- </button>
The camelCase naming (onClick, onChange, onMouseEnter, onKeyDown) matches how other JSX props are written, and it keeps event names consistent across every DOM element you use in React.
camelCase Names
onClick, onChange, onSubmit — not lowercase like in raw HTML attributes.
Real Functions
You pass an actual JavaScript function reference, not a string of code.
Same Elements
Any DOM element — button, input, form, div — can receive event props.
Passing a Function vs Calling It
One of the most common beginner mistakes is writing onClick={handleClick()} instead of onClick={handleClick}. These look similar but behave completely differently.
function Greeting() {
function sayHello() {
alert("Hello!");
}
return (
<div>
{/* Correct: passes the function itself */}
<button onClick={sayHello}>Say Hello (correct)</button>
{/* Wrong: calls the function immediately during render */}
<button onClick={sayHello()}>Say Hello (bug)</button>
</div>
);
}onClick={sayHello} -> stores the function, runs it only when clicked
onClick={sayHello()} -> calls sayHello immediately while rendering,
then passes its return value (undefined) to onClickonClick={handleClick} passes a reference — React will call it later, on click. onClick={handleClick()} calls the function right now, during render, which is almost never what you want.
Passing Arguments to Handlers
Sometimes a handler needs extra information — which item was clicked, for example. Since you cannot write onClick={handleClick(id)} (that calls it immediately), you wrap the call in an inline arrow function instead. The arrow function itself is passed as the reference, and it only calls handleClick when the click actually happens.
function ProductList() {
const products = ["Keyboard", "Mouse", "Monitor"];
function handleRemove(name) {
console.log("Removing:", name);
}
return (
<ul>
{products.map((name) => (
<li key={name}>
{name}
<button onClick={() => handleRemove(name)}>Remove</button>
</li>
))}
</ul>
);
}Removing: MouseonClick={() => handleRemove(name)} passes a brand-new function to onClick. React stores that function and only executes it — which in turn calls handleRemove(name) — at the moment the button is clicked.
The Synthetic Event Object
Whenever an event fires, React automatically passes an event object into your handler as the first argument. This is called a SyntheticEvent — a wrapper React provides around the browser's native event, designed to behave consistently across all browsers. It has the same familiar properties you already know, like target, type, and key.
The most common property you will reach for is event.target, which refers to the DOM element the event happened on. For a text input, event.target.value gives you exactly what the user typed.
function NameInput() {
function handleChange(event) {
console.log("You typed:", event.target.value);
}
return (
<input
type="text"
placeholder="Type your name"
onChange={handleChange}
/>
);
}You typed: S
You typed: Sa
You typed: Samevent.target
The DOM element the event happened on, e.g. the <input> that was typed into.
event.target.value
The current text/value inside an input, select, or textarea.
event.type
The name of the event that fired, like "click" or "change".
event.key
For keyboard events, which key was pressed, e.g. "Enter".
Preventing Default Behavior
Some DOM elements have built-in default behavior — clicking a submit button inside a form reloads the page, and clicking a link navigates away. In a React app you usually want to handle these actions yourself with JavaScript instead, so you call event.preventDefault() to stop the browser's default action.
function SimpleForm() {
function handleSubmit(event) {
event.preventDefault(); // stop the page from reloading
console.log("Form submitted without a page reload!");
}
return (
<form onSubmit={handleSubmit}>
<input type="text" placeholder="Your email" />
<button type="submit">Subscribe</button>
</form>
);
}Form submitted without a page reload!Without event.preventDefault(), submitting a form triggers a full browser page reload, wiping out all of your component state. Calling it lets you control exactly what happens next — like sending data to an API and updating the UI in place.
Common Mistakes
- Writing onClick={handleClick()} instead of onClick={handleClick}, which calls the function immediately during render.
- Forgetting event.preventDefault() in a form onSubmit handler, causing an unwanted page reload.
- Reading event.target.value outside the handler, after the event object has already been reused by React.
- Using lowercase HTML-style names like onclick instead of the camelCase onClick prop.
Best Practices
- Always pass a function reference (onClick={handleClick}), not a function call.
- Use an inline arrow function only when you need to pass extra arguments to a handler.
- Name handler functions clearly, like handleClick or handleSubmit, so their purpose is obvious.
- Call event.preventDefault() at the very start of a submit handler, before any other logic.
- Destructure event.target.value into a variable early if you use it more than once in a handler.
Frequently Asked Questions
Why does React use camelCase for events instead of lowercase?
It keeps event props consistent with the rest of JSX, where props like className and tabIndex are also camelCase, rather than mixing conventions.
Is the SyntheticEvent the same object as the native browser event?
It is a cross-browser wrapper around the native event with the same familiar API. In modern React it behaves very close to the native event, so you rarely need to think about the difference day to day.
Can I access the native event if I need to?
Yes, the synthetic event exposes a nativeEvent property if you ever need the underlying browser event directly.
Why do I need an arrow function to pass arguments?
Because onClick={handleClick(id)} would call handleClick immediately during render. Wrapping it as onClick={() => handleClick(id)} delays the call until the actual click happens.
Do I always need event.preventDefault() in a form?
You need it whenever you want to stop the browser's default submit behavior (a full page reload) and handle the submission yourself in JavaScript, which is the case in almost all React forms.
Key Takeaways
- React event props are camelCase, like onClick and onChange, and take a function.
- Pass the function itself (onClick={handleClick}) — calling it (handleClick()) runs it immediately during render.
- Wrap a handler in an arrow function, like () => handleClick(id), to pass custom arguments.
- Every handler receives a synthetic event object; event.target.value reads an input's current value.
- Call event.preventDefault() to stop default browser behavior, such as a form reloading the page.
Summary
Event handling in React follows a consistent, predictable pattern: camelCase props, function references instead of calls, and a synthetic event object that gives you everything you need, including event.target.value and preventDefault(). Once this pattern feels natural, wiring up clicks, input changes, and submissions becomes second nature.
In this lesson, you learned how React events differ from HTML, why passing a function reference matters, how to pass arguments with an arrow function, what the synthetic event object provides, and how to prevent default browser behavior. Next, you will learn how to conditionally render UI based on your application's state.
- You can wire up onClick, onChange, and onSubmit handlers correctly.
- You understand the difference between passing and calling a function.
- You can pass custom arguments to a handler using an arrow function.
- You know how to read event.target.value and call event.preventDefault().