Chapter 3 of 4
Typing Events and Refs
Getting handler and DOM types right without fighting the compiler.
React ships types for every synthetic event. The generic parameter is the element the handler is attached to.
function Form() {
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
console.log(event.target.value); // typed as string
}
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
}
function handleClick(event: React.MouseEvent<HTMLButtonElement>) {
console.log(event.currentTarget.name);
}
function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {
if (event.key === "Enter") submit();
}
}Let inference do the work
An inline handler does not need annotations at all - React's element types already describe the parameter.
// event is inferred as React.ChangeEvent<HTMLInputElement>
<input onChange={(event) => setValue(event.target.value)} />target versus currentTarget
currentTargetis the element the handler is on, and is typed precisely.targetis whatever was actually clicked, so it is typed as the more generalEventTarget.
Common DOM element types
HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement
HTMLButtonElement, HTMLFormElement, HTMLAnchorElement
HTMLDivElement, HTMLCanvasElement, HTMLVideoElementForwarding a ref
interface InputProps extends React.ComponentProps<"input"> {
label: string;
}
const TextField = forwardRef<HTMLInputElement, InputProps>(
function TextField({ label, ...rest }, ref) {
return (
<label>
{label}
<input ref={ref} {...rest} />
</label>
);
}
);