События клавиатуры и мыши
Клавиатура
onKeyDown
Срабатывает при нажатии:
function Input() {
function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
if (e.key === 'Enter') {
console.log('Enter нажат');
}
if (e.key === 'Escape') {
console.log('Escape');
}
}
return <input onKeyDown={handleKeyDown} />;
}
Свойства события
e.key— значение клавиши:'a','Enter','Escape','ArrowUp'e.code— физическая клавиша:'KeyA','Enter','ArrowUp'e.ctrlKey,e.shiftKey,e.altKey,e.metaKey— модификаторыe.repeat— повторное нажатие
Комбинации
function handleKeyDown(e: React.KeyboardEvent) {
if (e.ctrlKey && e.key === 's') {
e.preventDefault();
console.log('Сохранить');
}
if (e.metaKey && e.key === 'k') {
console.log('Открыть поиск');
}
}
На Mac Ctrl — это metaKey.
Ограничение ввода
<input
onKeyDown={(e) => {
if (!/^[0-9]$/.test(e.key) && e.key !== 'Backspace' && e.key !== 'Tab') {
e.preventDefault();
}
}}
/>
Enter в input
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
search(query);
}
}}
/>
Мышь
onClick
<button onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
console.log(e.clientX, e.clientY);
}}>Клик</button>
Свойства события
e.clientX,e.clientY— координаты относительно окнаe.pageX,e.pageY— относительно документаe.button— 0 (левая), 1 (средняя), 2 (правая)e.shiftKey,e.ctrlKey,e.altKey— модификаторы
Правый клик
<div onContextMenu={(e) => {
e.preventDefault();
console.log('Правый клик');
}}>...</div>
Наведение
<div
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
{hovered ? 'Наведено' : 'Наведи'}
</div>
onMouseEnter/onMouseLeave не всплывают. onMouseOver/onMouseOut — всплывают.
Движение мыши
<div onMouseMove={(e) => setPosition({ x: e.clientX, y: e.clientY })} />
Вызывается часто — следи за производительностью.
Двойной клик
<div onDoubleClick={() => console.log('двойной')} />
Глобальные события
События на window или document подписываются через useEffect:
useEffect(() => {
function handleKeyDown(e: KeyboardEvent) {
if (e.key === 'Escape') closeModal();
}
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);
}, []);
Фокус
<input
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
/>
onFocus — при получении фокуса, onBlur — при потере.
Фокус можно поставить программно через ref:
const inputRef = useRef<HTMLInputElement>(null);
inputRef.current?.focus();
Скролл
useEffect(() => {
function handleScroll() {
console.log(window.scrollY);
}
window.addEventListener('scroll', handleScroll, { passive: true });
return () => window.removeEventListener('scroll', handleScroll);
}, []);
{ passive: true } сообщает браузеру, что preventDefault не будет вызван — улучшает производительность.
Копирование
<input
onCopy={() => console.log('скопировано')}
onPaste={(e) => {
e.preventDefault();
const text = e.clipboardData.getData('text');
console.log(text);
}}
/>
Итоги
onKeyDownсe.keyдля клавиш- Комбинации через
e.ctrlKey,e.metaKey onClick,onMouseEnter,onMouseLeave- Глобальные события — через
useEffect onFocus/onBlurдля фокусаonScrollс{ passive: true }