Skip to main content

Як типізувати обробники подій?

Базовий принцип

  • Усі події - це нащадки React.SyntheticEvent.
  • У обробників є елемент, до якого вони прив'язані: HTMLInputElement, HTMLButtonElement, HTMLFormElement, HTMLDivElement тощо.
  • Зручні алiаси-коллбеки: React.MouseEventHandler<T>, React.ChangeEventHandler<T> та ін.
javascript
// Універсальний вигляд const handle = (e: React.SyntheticEvent<HTMLDivElement>) => { /* ... */ }; // З алiасом (рекомендовано, коротше) const onClick: React.MouseEventHandler<HTMLButtonElement> = (e) => { /* ... */ };

Часті випадки

Click (миша)

javascript
const onClick: React.MouseEventHandler<HTMLButtonElement> = (e) => { e.preventDefault(); };

Change (input, select, textarea)

javascript
const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => { const value = e.currentTarget.value; // коректно типізовано };

Submit (форма)

javascript
const onSubmit: React.FormEventHandler<HTMLFormElement> = (e) => { e.preventDefault(); };

Keyboard

javascript
const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => { if (e.key === "Enter") { /* ... */ } };

Focus / Blur

javascript
const onFocus: React.FocusEventHandler<HTMLInputElement> = (e) => { /* ... */ }; const onBlur: React.FocusEventHandler<HTMLTextAreaElement> = (e) => { /* ... */ };

Pointer / Mouse / Wheel

javascript
const onPointerDown: React.PointerEventHandler<HTMLDivElement> = (e) => {}; const onMouseEnter: React.MouseEventHandler<HTMLDivElement> = (e) => {}; const onWheel: React.WheelEventHandler<HTMLDivElement> = (e) => {};

Drag & Drop

javascript
const onDragStart: React.DragEventHandler<HTMLDivElement> = (e) => {}; const onDrop: React.DragEventHandler<HTMLDivElement> = (e) => { e.preventDefault(); };

Clipboard

javascript
const onPaste: React.ClipboardEventHandler<HTMLInputElement> = (e) => { const text = e.clipboardData.getData("text"); };

Touch (мобільні)

javascript
const onTouchStart: React.TouchEventHandler<HTMLDivElement> = (e) => {};

Animation / Transition

javascript
const onAnimationEnd: React.AnimationEventHandler<HTMLDivElement> = (e) => {}; const onTransitionEnd: React.TransitionEventHandler<HTMLDivElement> = (e) => {};

Цінні прийоми

1) target vs currentTarget

  • Використовуй e.currentTarget - він завжди того типу, до якого прив'язаний обробник.
  • e.target може бути вкладеним вузлом і типізується ширше (EventTarget).
javascript
const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => { // правильно e.currentTarget.value; // e.target.value - не скомпілюється без приведення типу };

2) Вбудовування прямо в пропси компонента

javascript
<button onClick={(e: React.MouseEvent<HTMLButtonElement>) => { /* ... */ }} />

3) Тип пропса-обробника у власних компонентах

javascript
type Props = { onClick?: React.MouseEventHandler<HTMLButtonElement>; }; const MyButton = ({ onClick }: Props) => <button onClick={onClick}>OK</button>;

Або "позичити" сигнатуру з нативного елемента:

javascript
type ButtonProps = { onClick?: React.ComponentProps<"button">["onClick"]; };

4) Обробник, що читає всю форму цілком

javascript
const onSubmit: React.FormEventHandler<HTMLFormElement> = (e) => { e.preventDefault(); const form = e.currentTarget; const data = new FormData(form); const email = data.get("email"); };

5) Універсальний колбек з generic

javascript
function handleChange<T extends HTMLInputElement | HTMLTextAreaElement>( e: React.ChangeEvent<T> ) { console.log(e.currentTarget.value); }

Швидкий довідник типів

  • React.MouseEvent<T> / React.MouseEventHandler<T>
  • React.ChangeEvent<T> / React.ChangeEventHandler<T>
  • React.FormEvent<T> / React.FormEventHandler<T>
  • React.KeyboardEvent<T> / React.KeyboardEventHandler<T>
  • React.FocusEvent<T> / React.FocusEventHandler<T>
  • React.PointerEvent<T> / React.PointerEventHandler<T>
  • React.DragEvent<T> / React.DragEventHandler<T>
  • React.ClipboardEvent<T> / React.ClipboardEventHandler<T>
  • React.WheelEvent<T> / React.WheelEventHandler<T>
  • React.TouchEvent<T> / React.TouchEventHandler<T>
  • React.AnimationEvent<T> / React.AnimationEventHandler<T>
  • React.TransitionEvent<T> / React.TransitionEventHandler<T>

Де T - конкретний DOM-елемент: HTMLInputElement, HTMLButtonElement, HTMLDivElement, HTMLFormElement, HTMLSelectElement, HTMLTextAreaElement, HTMLAnchorElement тощо.


Часті помилки

  • any в обробниках - втрачаєш підказки і перевірки.
  • Використання e.target замість e.currentTarget.
  • Забули вказати тип елемента (наприклад, HTMLInputElement) - доведеться вручну приводити тип target.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.