Типизация событий в React

Типизация событий в React позволяет точно описывать объект события (event), который передаётся в обработчики. Это даёт доступ к правильным свойствам (например, e.target.value) и предотвращает ошибки при работе с формами, кликами и другими взаимодействиями.

Общая форма типизации

Все события в React обёрнуты в синтетические объекты, предоставляемые библиотекой. Их типы находятся в пространстве имён React. Пример:

function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
  console.log(e.target.value);
}

Здесь React.ChangeEvent<HTMLInputElement> говорит TypeScript, что:

  • событие — это изменение значения (change),
  • цель события — HTML-элемент типа <input>,
  • у e.target есть свойство value.

Распространённые типы событий

  • React.ChangeEvent<HTMLInputElement> — для полей ввода.
  • React.FormEvent<HTMLFormElement> — для отправки формы.
  • React.MouseEvent<HTMLButtonElement> — для кликов по кнопке.
  • React.KeyboardEvent<HTMLInputElement> — для нажатий клавиш в поле ввода.

Пример обработчика клика:

function handleClick(e: React.MouseEvent<HTMLButtonElement>) {
  e.preventDefault();
  console.log('Кнопка нажата');
}

Почему важно указывать точный тип

Если использовать общий тип any или не указывать тип вообще, IDE не сможет предложить автодополнение, а TypeScript не защитит от обращения к несуществующим свойствам:

// Плохо:
function badHandler(e) {
  console.log(e.target.valu); // опечатка — ошибка не будет найдена
}

// Хорошо:
function goodHandler(e: React.ChangeEvent<HTMLInputElement>) {
  console.log(e.target.valu); // ошибка на этапе компиляции
}

Упрощение через переиспользование типов

Если обработчик используется в нескольких местах, можно вынести тип:

type InputChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;

const handleChange: InputChangeHandler = (e) => {
  setValue(e.target.value);
};

Это особенно полезно в больших компонентах или при написании кастомных хуков.