Handle user interactions with typed event handlers in React.
React uses camelCase event props like onClick, onChange, onSubmit instead of HTML's lowercase attributes.
function Button() {
function handleClick() {
console.log("clicked!");
}
return <button onClick={handleClick}>Click me</button>;
}
Every handler receives a typed event object. TypeScript knows the exact type based on the element:
// Input change
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
console.log(e.target.value);
}
// Form submit
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
// process form
}
// Button click
function handleClick(e: React.MouseEvent<HTMLButtonElement>) {
console.log("x:", e.clientX, "y:", e.clientY);
}
A controlled input stores its value in state and updates state on every change. React is the single source of truth:
function SearchBox() {
const [query, setQuery] = useState("");
return (
<input
value={query}
onChange={e => setQuery(e.target.value)}
placeholder="Search..."
/>
);
}
Build a controlled form with:
<input> that tracks its value in state<button type="submit"> or form onSubmit handler that prevents the default reload<p> that shows You typed: {value} reflecting the current input in real time<ul> that shows submitted values as <li> items — each submit appends the current value to a list (and clears the input)import { useState } from "react"; export default function App() { const [value, setValue] = useState(""); const [items, setItems] = useState<string[]>([]); function handleSubmit(e: React.FormEvent<HTMLFormElement>) { e.preventDefault(); // Add value to items and clear input } return ( <form onSubmit={handleSubmit}> <input value={value} onChange={e => setValue(e.target.value)} placeholder="Type something..." /> <button type="submit">Add</button> <p>You typed: {value}</p> <ul> {/* render items here */} </ul> </form> ); }