Events let your components respond to user interaction — clicks, key presses, form submissions, and more.
Click events
JSX
function LikeButton() {
const [liked, setLiked] = useState(false);
return (
<button onClick={() => setLiked(!liked)}>
{liked ? '❤️' : '🤍'} {liked ? 'Liked!' : 'Like'}
</button>
);
}Event parameters
JSX
function TodoItem({ todo, onToggle, onDelete }) {
return (
<div>
<span onClick={() => onToggle(todo.id)}>
{todo.done ? '✅' : '⬜'} {todo.text}
</span>
<button onClick={() => onDelete(todo.id)}>Delete</button>
</div>
);
}Form events
JSX
function SearchBox() {
const [query, setQuery] = useState('');
const handleSubmit = (e) => {
e.preventDefault(); // Prevent page reload
console.log('Searching:', query);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
<button type="submit">Search</button>
</form>
);
}Controlled inputs
JSX
function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
return (
<form>
<input type="email" value={email}
onChange={e => setEmail(e.target.value)} />
<input type="password" value={password}
onChange={e => setPassword(e.target.value)} />
<button type="submit">Log in</button>
</form>
);
}In React, form inputs are controlled — their value is driven by
state, and changes go through onChange. This gives you full control
over the input at all times.
Event propagation
JSX
function Modal({ onClose }) {
return (
<div onClick={onClose}>
<div onClick={(e) => e.stopPropagation()}>
{/* Clicking inside doesn't close */}
<h2>Modal</h2>
<p>Content here</p>
</div>
</div>
);
}Tips
- Always call
e.preventDefault()in form submissions. - Use controlled inputs (
value+onChange) — not uncontrolled (ref). - Use
e.stopPropagation()to prevent events from bubbling up. - Keep event handlers small — extract logic into separate functions.
Next: lists.