События в React
Событие — это действие пользователя или браузера: клик, ввод текста, отправка формы, нажатие клавиши. React предоставляет единый синтетический слой над DOM-событиями.
Синтетические события
React оборачивает нативные события в SyntheticEvent. Это объект с тем же интерфейсом, что и нативное событие, но работающий одинаково во всех браузерах.
function Button() {
function handleClick(e: React.MouseEvent<HTMLButtonElement>) {
console.log(e.type); // click
console.log(e.target); // кнопка
}
return <button onClick={handleClick}>Нажми</button>;
}
Именование
В React события пишутся в camelCase: onClick, onChange, onSubmit. В HTML — onclick, onchange, onsubmit.
Передача функции
Передаётся функция, а не её вызов:
<button onClick={handleClick}>OK</button> // правильно
<button onClick={handleClick()}>Ошибка</button> // вызовется при рендере
Если нужен вызов с аргументом — оборачивай в стрелочную функцию:
<button onClick={() => handleDelete(id)}>Удалить</button>
Основные события
- onClick — клик мышью
- onDoubleClick — двойной клик
- onChange — изменение значения input, select, textarea
- onInput — ввод в поле
- onSubmit — отправка формы
- onFocus / onBlur — фокус и потеря фокуса
- onMouseEnter / onMouseLeave — вход/выход мыши
- onMouseDown / onMouseUp — нажатие/отпускание кнопки мыши
- onKeyDown / onKeyUp / onKeyPress — клавиши
- onScroll — прокрутка
- onLoad — загрузка
- onError — ошибка
- onCopy / onPaste / onCut — буфер обмена
- onDragStart / onDrop — drag-and-drop
Объект события
function Input() {
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
console.log(e.target.value);
console.log(e.target.name);
console.log(e.target.type);
}
return <input onChange={handleChange} />;
}
e.target — элемент, на котором произошло событие. e.currentTarget — элемент, к которому привязан обработчик.
preventDefault
Отменяет поведение браузера по умолчанию:
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
// обработка без перезагрузки
}
Примеры:
- Форма — не перезагружать страницу
- Ссылка — не переходить по URL
- Клавиша — не вводить символ
stopPropagation
Останавливает всплытие события:
function Card() {
return (
<div onClick={() => console.log('card')}>
<button onClick={(e) => {
e.stopPropagation();
console.log('button');
}}>
OK
</button>
</div>
);
}
Без stopPropagation клик по кнопке вызовет оба обработчика.
Типизация событий
TypeScript позволяет точно указать тип события:
function handleClick(e: React.MouseEvent<HTMLButtonElement>) {}
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {}
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {}
function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {}
function handleFocus(e: React.FocusEvent<HTMLInputElement>) {}
Обработчик в родителе
Часто обработчик живёт в родителе, а вызывается в ребёнке:
function Parent() {
function handleDelete(id: number) {
console.log(id);
}
return <Child onDelete={handleDelete} />;
}
function Child({ onDelete }: { onDelete: (id: number) => void }) {
return <button onClick={() => onDelete(5)}>Удалить</button>;
}
Итоги
- События — camelCase
- Передаётся функция, не вызов
- SyntheticEvent работает одинаково в браузерах
preventDefaultотменяет поведение по умолчаниюstopPropagationостанавливает всплытие- Тип события —
React.MouseEvent<HTMLButtonElement>и т. д.