React events work very similarly to DOM events, but with a few differences:
event handler uses lowercase: onclick
function is a string: "handleClick()"
this often needs binding
uses camelCase: onClick
function is passed directly: {handleClick}
functional components avoid this problem
function App() {
function handleClick() {
console.log("Button clicked!");
}
return (
<button onClick={handleClick}>
Click Me
</button>
);
}
You pass the function, not call it.
❌ onClick={handleClick()}
✅ onClick={handleClick}
function App() {
function handleGreet(name) {
console.log(`Hello ${name}`);
}
return (
<button onClick={() => handleGreet("Alice")}>
Greet
</button>
);
}
Handling forms in React usually means using controlled components.
A controlled component is an input whose value is controlled by React state.
import { useState } from "react";
function App() {
const [name, setName] = useState("");
function handleSubmit(e) {
e.preventDefault(); // prevents page reload
console.log("Submitted name:", name);
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter name"
/>
<button type="submit">Submit</button>
</form>
);
}
value={name} → input always reflects state.
onChange={...} → updates the state when user types.
onSubmit → React handles form submission without reload.
Always use e.preventDefault() when handling form submits → Prevents page refresh.
Inputs must always have value and onChange → This ensures they stay controlled.
Don’t mutate state directly → Always copy (...form), then update.
Use one state object:
function App() {
const [form, setForm] = useState({
username: "",
password: ""
});
function handleChange(e) {
setForm({
...form,
[e.target.name]: e.target.value
});
}
function handleSubmit(e) {
e.preventDefault();
console.log(form);
}
return (
<form onSubmit={handleSubmit}>
<input
name="username"
value={form.username}
onChange={handleChange}
/>
<input
type="password"
name="password"
value={form.password}
onChange={handleChange}
/>
<button>Login</button>
</form>
);
}
This approach is scalable for large forms.