Typing Events
React wraps browser events in its own event types.
TypeScript helps you know which properties are available for each element and event.
Input Change Events
function EmailField() {
const [email, setEmail] = useState("");
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
setEmail(event.currentTarget.value);
}
return <input type="email" value={email} onChange={handleChange} />;
}HTMLInputElement tells TypeScript that currentTarget.value exists.
Prefer currentTarget when reading the element the handler is attached to.
Inline Handlers Can Infer Types
<input
value={name}
onChange={(event) => {
setName(event.currentTarget.value);
}}
/>;TypeScript often infers event correctly for inline handlers.
When extracting the function, add the event type.
Form Submit Events
function SignupForm() {
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
const form = event.currentTarget;
const formData = new FormData(form);
const email = String(formData.get("email") ?? "");
console.log(email);
}
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" />
<button type="submit">Sign up</button>
</form>
);
}Use preventDefault when you want React to handle the submission instead of the browser navigating.
Button Click Events
function SaveButton() {
function handleClick(event: React.MouseEvent<HTMLButtonElement>) {
event.currentTarget.disabled = true;
}
return <button onClick={handleClick}>Save</button>;
}Usually you should update React state instead of mutating DOM properties directly.
This example shows the event type, not the preferred state pattern.
Keyboard Events
function SearchInput() {
function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {
if (event.key === "Escape") {
event.currentTarget.blur();
}
}
return <input onKeyDown={handleKeyDown} />;
}Avoid relying on deprecated key codes.
Use event.key for readable behavior.
Common Mistakes
- Using the broad
Eventtype instead of React event types. - Reading from
event.targetwhencurrentTargetis the safer choice. - Forgetting to type extracted event handlers.
- Mutating DOM directly instead of updating state.
- Handling keyboard events in ways that break expected accessibility behavior.
Which type is appropriate for an extracted text input onChange handler?
Practical Challenge
Create a typed SearchForm component.
It should:
- track a text input
- submit through a typed form event
- clear the field when Escape is pressed
- call
onSearch(query: string)when submitted
Use extracted handler functions with explicit event types.
Recap
Type React events based on the event kind and the HTML element.
Use inference for small inline handlers, and add explicit React event types when extracting reusable functions.