Типизация событий и ссылок в TypeScript
Используйте обобщения React.ChangeEvent, React.MouseEvent и RefObject для взаимодействия с DOM.
«Типизация событий и ссылок в TypeScript» — бесплатный урок React Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.
Синтетические события React
React оборачивает нативные события DOM в SyntheticEvent. Для каждого типа события предусмотрен специальный обобщённый тип: React.ChangeEvent<HTMLInputElement>, React.MouseEvent<HTMLButtonElement> и так далее.
Типизация onChange
Самое распространённое событие — onChange у полей ввода. Типизируйте его обработчик с помощью React.ChangeEvent<HTMLInputElement>.
function SearchInput() {
const [value, setValue] = useState('');
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
};
return <input value={value} onChange={handleChange} />;
}Типизация onClick
Щелчки по кнопкам используют React.MouseEvent<HTMLButtonElement>. При полной типизации можно безопасно обращаться к e.currentTarget, e.preventDefault() и e.stopPropagation().
function DeleteButton({ onDelete }: { onDelete: () => void }) {
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
e.stopPropagation();
onDelete();
};
return <button onClick={handleClick}>Delete</button>;
}Типизация onSubmit
Отправка формы использует React.FormEvent<HTMLFormElement>. Всегда вызывайте e.preventDefault(), чтобы остановить стандартную навигацию браузера.
function LoginForm() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const form = e.currentTarget;
const email = (form.elements.namedItem('email') as HTMLInputElement).value;
console.log(email);
};
return (
<form onSubmit={handleSubmit}>
<input name="email" />
<button type="submit">Login</button>
</form>
);
}Типизация событий клавиатуры
Используйте React.KeyboardEvent<HTMLElement> для типизации обработчиков клавиатуры. Безопасно обращайтесь к e.key, e.code и e.ctrlKey.
function CommandInput() {
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter' && e.metaKey) {
submitCommand();
}
};
return <input onKeyDown={handleKeyDown} />;
}useRef для элементов DOM
Передайте тип HTML-элемента в качестве обобщённого типа для useRef и инициализируйте его значением null. Тогда TypeScript будет знать, что ссылка содержит элемент этого типа.
function AutoFocusInput() {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
inputRef.current?.focus();
}, []);
return <input ref={inputRef} />;
}Изменяемая ссылка и ссылка на DOM
Если Вы храните изменяемое значение, а не узел DOM, инициализируйте useRef значением вместо null. TypeScript выведет изменяемый тип MutableRefObject.
// DOM ref (read-only current)
const divRef = useRef<HTMLDivElement>(null);
// Mutable ref (read-write current)
const countRef = useRef<number>(0);
countRef.current += 1; // ✓ no TypeScript errorТипизация useImperativeHandle
Если Вы предоставляете API ссылки из дочернего компонента, определите интерфейс для этого API и используйте его и в forwardRef, и в useImperativeHandle.
interface DialogHandle {
open: () => void;
close: () => void;
}
const Dialog = forwardRef<DialogHandle, { title: string }>((props, ref) => {
useImperativeHandle(ref, () => ({
open: () => console.log('open'),
close: () => console.log('close'),
}));
return <div>{props.title}</div>;
});Колбэки ссылок
Колбэк ссылки получает HTML-элемент или значение null. Типизируйте его как (node: HTMLElement | null) => void.
function MeasureDiv() {
const [height, setHeight] = useState(0);
const measuredRef = (node: HTMLDivElement | null) => {
if (node) setHeight(node.getBoundingClientRect().height);
};
return <div ref={measuredRef}>Content: {height}px tall</div>;
}Цель события и текущая цель
e.target — это элемент, вызвавший событие, а e.currentTarget — элемент, к которому прикреплён обработчик. Приводите e.target к нужному типу, когда требуются определённые свойства.
const handleClick = (e: React.MouseEvent<HTMLUListElement>) => {
const target = e.target as HTMLLIElement;
console.log(target.dataset.id);
};Тип обобщённого обработчика событий
Чтобы писать повторно используемые функции-обработчики событий, используйте обобщённый тип React.EventHandler<Event> или просто указывайте полную сигнатуру функции непосредственно в коде.
type InputChangeHandler = React.ChangeEventHandler<HTMLInputElement>;
const logChange: InputChangeHandler = (e) => {
console.log(e.target.value); // e is fully typed
};Быстрая проверка
Какой тип TypeScript следует использовать для useRef, содержащего HTMLInputElement?
Повторение
Типизируйте обработчики событий с помощью обобщённых типов React.ChangeEvent, React.MouseEvent и React.FormEvent. Типизируйте ссылки на DOM с помощью useRef<HTMLElement>(null), а изменяемые ссылки — типом хранимого значения. Используйте forwardRef с явным интерфейсом API для императивных операций.
Часто задаваемые вопросы
Урок «Типизация событий и ссылок в TypeScript» бесплатный?
Да — полный текст урока «Типизация событий и ссылок в TypeScript» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.
Чему я научусь в уроке «Типизация событий и ссылок в TypeScript»?
Используйте обобщения React.ChangeEvent, React.MouseEvent и RefObject для взаимодействия с DOM. Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать React Academy?
Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Типизация событий и ссылок в TypeScript»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке React Academy?
Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Типизация свойств и возвращаемых типов компонентов
- Типизация событий и ссылок в TypeScript
- Обобщённые компоненты и вспомогательные типы
- Типизация контекста и пользовательских хуков