Типизация событий
React оборачивает нативные события в SyntheticEvent. Для каждого типа события есть свой тип.
onClick
import type { MouseEvent } from 'react';
function Button() {
function handleClick(e: MouseEvent<HTMLButtonElement>) {
console.log(e.clientX, e.clientY);
}
return <button onClick={handleClick}>OK</button>;
}
MouseEvent<HTMLButtonElement> — событие мыши на кнопке.
onChange
import type { ChangeEvent } from 'react';
function Input() {
function handleChange(e: ChangeEvent<HTMLInputElement>) {
console.log(e.target.value);
}
return <input onChange={handleChange} />;
}
Для <select>:
function Select() {
function handleChange(e: ChangeEvent<HTMLSelectElement>) {
console.log(e.target.value);
}
return <select onChange={handleChange} />;
}
Для <textarea>:
function Textarea() {
function handleChange(e: ChangeEvent<HTMLTextAreaElement>) {
console.log(e.target.value);
}
return <textarea onChange={handleChange} />;
}
onSubmit
import type { FormEvent } from 'react';
function Form() {
function handleSubmit(e: FormEvent<HTMLFormElement>) {
e.preventDefault();
const data = new FormData(e.currentTarget);
}
return <form onSubmit={handleSubmit}>...</form>;
}
onKeyDown
import type { KeyboardEvent } from 'react';
function Input() {
function handleKeyDown(e: KeyboardEvent<HTMLInputElement>) {
if (e.key === 'Enter') {
console.log('Enter');
}
}
return <input onKeyDown={handleKeyDown} />;
}
onFocus и onBlur
import type { FocusEvent } from 'react';
function Input() {
function handleFocus(e: FocusEvent<HTMLInputElement>) {
console.log('focused');
}
return <input onFocus={handleFocus} />;
}
onMouseEnter, onMouseLeave
function Card() {
function handleEnter(e: MouseEvent<HTMLDivElement>) {}
function handleLeave(e: MouseEvent<HTMLDivElement>) {}
return <div onMouseEnter={handleEnter} onMouseLeave={handleLeave} />;
}
onScroll
import type { UIEvent } from 'react';
function Scroller() {
function handleScroll(e: UIEvent<HTMLDivElement>) {
console.log(e.currentTarget.scrollTop);
}
return <div onScroll={handleScroll} />;
}
onDrag
import type { DragEvent } from 'react';
function Draggable() {
function handleDragStart(e: DragEvent<HTMLDivElement>) {
e.dataTransfer.setData('text', 'hello');
}
return <div draggable onDragStart={handleDragStart} />;
}
onTouch
import type { TouchEvent } from 'react';
function Button() {
function handleTouch(e: TouchEvent<HTMLButtonElement>) {
console.log(e.touches[0].clientX);
}
return <button onTouchStart={handleTouch}>OK</button>;
}
Inline-обработчик
Если обработчик короткий — тип можно не указывать:
<button onClick={(e) => console.log(e.clientX)}>OK</button>
TypeScript выведет тип из контекста.
currentTarget vs target
function Form() {
function handleSubmit(e: FormEvent<HTMLFormElement>) {
e.currentTarget; // HTMLFormElement — надёжно
e.target; // EventTarget | null — нужно сужать
}
}
currentTarget — элемент, к которому привязан обработчик. target — на чём произошло событие (может быть вложенный).
Итоги
- Типы событий из
react MouseEvent<T>,ChangeEvent<T>,FormEvent<T>- Generic
T— тип элемента - Inline-обработчики выводят тип автоматически
currentTargetнадёжнееtarget