Event handlers let your app respond when users click, type, or interact. They make your page feel alive and interactive.
Event handlers in client components in NextJS
function MyComponent() { function handleClick(event) { // code to run on click } return ( <button onClick={handleClick}>Click me</button> ) }
Use camelCase for event names like onClick, onChange, etc.
Pass a function reference, not a function call, to the event handler.
function MyComponent() { function handleClick() { alert('Button clicked!') } return <button onClick={handleClick}>Click me</button> }
function MyComponent() { const [count, setCount] = React.useState(0) function increment() { setCount(count + 1) } return <button onClick={increment}>Clicked {count} times</button> }
function MyComponent() { function handleInputChange(event) { console.log('Input value:', event.target.value) } return <input type="text" onChange={handleInputChange} aria-label="Name input" /> }
This component shows a button that counts how many times you click it. Each click updates the number shown on the button.
It uses React's useState hook to keep track of the count and an onClick event handler to update it.
The button has an aria-label for accessibility, so screen readers can describe it properly.
'use client'; import React, { useState } from 'react' export default function ClickCounter() { const [count, setCount] = useState(0) function handleClick() { setCount(count + 1) } return ( <main style={{ padding: '1rem', fontFamily: 'Arial, sans-serif' }}> <button onClick={handleClick} aria-label="Increment counter" style={{ fontSize: '1.25rem', padding: '0.5rem 1rem' }}> Clicked {count} times </button> </main> ) }
Always use aria-label or visible text for buttons to help screen readers.
Event handlers receive an event object with useful info like which key was pressed or the target element.
Keep event handler functions small and focused for easier debugging.
Event handlers let your app respond to user actions like clicks and typing.
Use camelCase event names and pass function references in JSX.
React's useState works well with event handlers to update UI dynamically.
Practice
Solution
Step 1: Understand React event handler syntax
React and Next.js use camelCase event names and expect a function reference, not a string.Step 2: Identify correct JSX usage
The correct way isonClick={handleClick}, passing the function directly.Final Answer:
UseonClick={handleClick}with a function reference. -> Option DQuick Check:
React event handlers use camelCase and function references [OK]
- Using lowercase 'onclick' attribute as string
- Passing event handler as a string instead of function
- Omitting 'on' prefix in event name
Solution
Step 1: Check arrow function syntax
const handleClick = () => { alert('Clicked!'); } correctly defines an arrow function with braces and a statement inside.Step 2: Compare other options
const handleClick = () => alert('Clicked!'); uses concise arrow function syntax without braces; function handleClick() { alert('Clicked!'); } uses traditional function declaration; const handleClick = alert('Clicked!'); calls alert immediately, not defining a function.Final Answer:
const handleClick = () => { alert('Clicked!'); } -> Option AQuick Check:
Arrow function with braces and alert call is correct [OK]
- Calling alert immediately instead of wrapping in function
- Missing braces for multiple statements
- Using old function syntax unnecessarily
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
return (
Clicked {count} times
);
}Solution
Step 1: Understand useState and event handler
The state variable 'count' starts at 0 and increments by 1 on each click via setCount.Step 2: Predict UI update on click
Clicking the button calls increment, updating count and re-rendering button text with new count.Final Answer:
Button text updates to 'Clicked 1 times' on first click and increments thereafter. -> Option BQuick Check:
useState updates UI dynamically on event [OK]
- Not using useState to update UI
- Calling setCount incorrectly
- Expecting static text without re-render
import { useState } from 'react';
export default function Toggle() {
const [on, setOn] = useState(false);
function toggle() {
setOn(!on);
}
return (
{on ? 'ON' : 'OFF'}
);
}Solution
Step 1: Check event handler attribute spelling
React and Next.js require camelCase event names, so 'onclick' is incorrect; it must be 'onClick'.Step 2: Validate other code parts
Using setOn(!on) works but can cause stale state; initial boolean is valid; wrapping button is not required.Final Answer:
The event handler attribute should be 'onClick' with capital C. -> Option CQuick Check:
Event handlers use camelCase 'onClick' [OK]
- Using lowercase 'onclick' instead of 'onClick'
- Ignoring stale state issues in setState
- Thinking JSX requires fragments for single elements
import { useState } from 'react';
export default function Greeting() {
const [name, setName] = useState('');
// What should the input's onChange handler be?
return (
Hello, {name || 'stranger'}!
);
}Solution
Step 1: Understand event handler for input changes
The onChange handler receives an event; to update state, call setName with event target's value.Step 2: Identify correct arrow function syntax
onChange={e => setName(e.target.value)} correctly defines an arrow function that takes event and calls setName with e.target.value.Final Answer:
onChange={e => setName(e.target.value)} -> Option AQuick Check:
Use event parameter to update state from input value [OK]
- Calling setName immediately instead of in a function
- Not passing event parameter to handler
- Returning value without updating state
Ready to prove it?
Pass the test and this pattern moves unknown
