Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Як типізувати обробники подій?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Усі події в React - це нащадки `React.SyntheticEvent`, і в обробників є **елемент**, до якого вони прив'язані (`HTMLInputElement`, `HTMLButtonElement` тощо), а для зручності є алiаси-коллбеки на кшталт `React.MouseEventHandler<T>` чи `React.ChangeEventHandler<T>`. **Ключове:** завжди використовуй `e.currentTarget` замість `e.target` - він точно типізований під елемент, до якого прив'язаний обробник.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Базовий принцип - Усі події - це нащадки `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`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.