Events
By the end of this lesson you'll be able to make buttons, inputs, and forms do something — wiring up onClick , onChange , and onSubmit handlers, reading the event object, and stopping the page from reloading.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free React course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
1. Click Events & Handler Functions
An event is something the user does — a click, a keypress, a form submit. An event handler is a function you write that runs in response. In React you attach one with a camelCase prop like onClick (not the lowercase onclick from HTML), and you pass the function by name . The golden rule: {'onClick= '} — no parentheses. The parentheses would call the function immediately; you want to hand the function to React so it can call it on each click.
Read the worked example below. The handleLike function is exactly what you'd pass to onClick — here we call it three times to simulate three clicks and watch the count climb.
This single distinction trips up almost every beginner. Burn it in now:
Now you try. Finish the handler and "click" the button by calling it.
2. Passing Arguments to Handlers
What if your handler needs data — like which item to delete? You can't write {'onClick= '} because, as you just learned, that calls deletePost immediately during render. The fix is an arrow wrapper : {'onClick= '} . The arrow function is the handler; it sits and waits, and only calls deletePost(id) when the click actually happens.
3. The Event Object & onChange
When React calls your handler, it passes one argument: the event object . React calls it a SyntheticEvent — a cross-browser wrapper around the native DOM event, so the same properties work in every browser. The one you'll use constantly is e.target.value : the current text of an input. The onChange event fires on every keystroke, which is how you keep React state in sync with what the user types (a controlled component ).
In real JSX, that handler wires an input to state like this:
4. Forms & preventDefault()
Forms have a built-in browser behaviour: submitting one reloads the page . In a React app that's a disaster — a reload throws away all your state and re-fetches everything. So in your onSubmit handler you call e.preventDefault() as the very first line. That cancels the default reload and lets you handle the submit in JavaScript instead. Put it on {' '} , not the button — that way pressing Enter inside the form works too.
Your turn — complete the submit handler so the page is never reloaded and the typed email is logged.
JSX uses camelCase for event props, so it's onClick , onChange , onSubmit . It's also a different mechanism from HTML — you pass a real JavaScript function, not a string of code.
Q: When do I need the arrow function wrapper?
Only when you need to pass an argument, e.g. {'onClick= '} . If the handler takes no arguments, pass it by name: {'onClick= '} .
Q: Where does the e in handleChange(e) come from?
React passes it automatically. Whenever your handler is the one React calls directly, the first argument is the SyntheticEvent — just add an e parameter to receive it.
Q: What happens if I forget e.preventDefault() in a form?
The browser does its default thing and reloads the page, which destroys your React state and re-runs the whole app. Always call it first in an onSubmit handler.
No blanks this time — just a brief and an outline. Write the handler yourself, "click" it three times, and match the expected output. This is the exact pattern behind every show/hide, dark-mode, and accordion button you'll ever build.
Practice quiz
How do you correctly attach a click handler in JSX?
- onClick={handleClick()}
- onclick={handleClick}
- onClick={handleClick}
- onClick="handleClick"
Answer: onClick={handleClick}. Pass the function by name without parentheses: onClick={handleClick}. React calls it on each click.
What does onClick={handleClick()} do?
- Calls handleClick immediately during render and uses its return value as the handler
- Calls handleClick on each click
- Nothing
- Throws a syntax error
Answer: Calls handleClick immediately during render and uses its return value as the handler. The parentheses call it right away at render time; the return value (often undefined) becomes the handler.
Why does JSX use onClick rather than the HTML onclick?
- They are the same thing
- onclick is deprecated in browsers
- onClick is faster
- JSX uses camelCase event props and passes a function, not a string
Answer: JSX uses camelCase event props and passes a function, not a string. JSX event props are camelCase (onClick, onChange) and take a real JavaScript function, not a code string.
How do you pass an argument to a handler on click?
- onClick={deletePost(id)}
- onClick={() => deletePost(id)}
- onClick={deletePost, id}
- onClick={deletePost.bind(id)}
Answer: onClick={() => deletePost(id)}. Wrap it in an arrow function: onClick={() => deletePost(id)} so the call is delayed until the click.
What does React call the event object passed to your handler?
- A SyntheticEvent
- A NativeEvent
- A DOMEvent
- A ReactEvent
Answer: A SyntheticEvent. React passes a SyntheticEvent — a cross-browser wrapper around the native DOM event.
In an onChange handler, how do you read the current text of an input?
- e.value
- e.input.text
- e.target.value
- e.currentValue
Answer: e.target.value. e.target.value holds the input's current text; onChange fires on every keystroke.
Why call e.preventDefault() in a form's onSubmit handler?
- To submit faster
- To stop the browser from reloading the page (which wipes React state)
- To clear the form
- To focus the first input
Answer: To stop the browser from reloading the page (which wipes React state). By default a form submit reloads the page, destroying React state; preventDefault stops that.
Where should you put the onSubmit handler so Enter-to-submit works?
- On the submit button
- On each input
- On the document
- On the <form> element
Answer: On the <form> element. Put onSubmit on the <form>; then both button clicks and pressing Enter trigger it.
You get 'Cannot read properties of undefined (reading value)' in handleChange. Likely cause?
- The input has no value
- You forgot to accept the event parameter e
- You used onClick instead of onChange
- preventDefault was missing
Answer: You forgot to accept the event parameter e. The handler must accept the event: function handleChange(e) — then read e.target.value.
What commonly causes 'Maximum update depth exceeded' with an onClick?
- Using an arrow wrapper
- Reading e.target.value
- Calling setState during render, e.g. onClick={setCount(count + 1)}
- Putting onSubmit on the form
Answer: Calling setState during render, e.g. onClick={setCount(count + 1)}. onClick={setCount(...)} runs setState during render, re-rendering and re-calling it. Use onClick={() => setCount(...)}.