Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между Events в React и нативном DOM
Это важный вопрос, потому что React имеет свою систему обработки событий, которая отличается от стандартного DOM API. Разработчик должен понимать эти различия для отладки и оптимизации.
Нативный DOM
В стандартном JavaScript события работают так:
// Добавляем слушатель к элементу
const button = document.querySelector('button');
button.addEventListener('click', (event) => {
console.log('Клик!', event);
});
// Удаляем слушатель
button.removeEventListener('click', handleClick);
Фазы события в DOM:
- Capturing (захват) - событие идёт от window к целевому элементу
- Target (целевой элемент) - событие на самом элементе
- Bubbling (всплытие) - событие идёт от целевого элемента к window
const parent = document.querySelector('.parent');
const child = document.querySelector('.child');
// Фаза захвата
parent.addEventListener('click', () => console.log('Parent capture'), true);
// Фаза всплытия (по умолчанию)
parent.addEventListener('click', () => console.log('Parent bubble'));
child.addEventListener('click', () => console.log('Child'));
// При клике на child выведет:
// Parent capture
// Child
// Parent bubble
Event Delegation (делегирование событий)
В нативном DOM можно использовать делегирование для оптимизации:
// Вместо того, чтобы слушать каждый элемент...
const items = document.querySelectorAll('li');
items.forEach(item => {
item.addEventListener('click', handleClick);
});
// Слушаем один раз на родителе
const list = document.querySelector('ul');
list.addEventListener('click', (event) => {
if (event.target.tagName === 'LI') {
handleClick(event);
}
});
React Events (Synthetic Events)
React не использует прямо нативные события. Вместо этого использует Synthetic Events System:
// В React обработчик не привязан к конкретному элементу
function Button() {
const handleClick = (event) => {
// event это не нативный Event, а SyntheticEvent от React
console.log(event.type); // 'click'
console.log(event.target); // DOM элемент
};
return <button onClick={handleClick}>Клик</button>;
}
Как React обрабатывает события:
- React не добавляет слушателей к каждому элементу
- Вместо этого добавляет один слушатель к корню документа (или контейнеру)
- Использует делегирование событий для обработки
- При клике обходит компоненты и вызывает нужные обработчики
// Так React работает внутри (упрощённо)
const root = document.getElementById('root');
root.addEventListener('click', (nativeEvent) => {
// React обходит дерево компонентов
// и вызывает обработчики onClick
const handlers = findHandlersInTree(nativeEvent.target);
handlers.forEach(handler => handler(syntheticEvent));
});
Ключевые отличия
| Аспект | Нативный DOM | React |
|---|---|---|
| Способ подписки | addEventListener | Атрибуты вроде onClick |
| Полинг событий | На каждом элементе | Делегирование на корень |
| Объект события | Нативный Event | SyntheticEvent (обёртка) |
| Производительность | Может быть медленным для больших списков | Оптимизировано через делегирование |
| Доступ к нативному Event | Прямой доступ | event.nativeEvent |
Доступ к нативному Event в React
Иногда нужно использовать нативный Event:
function Component() {
const handleClick = (syntheticEvent) => {
// Получить нативное событие
const nativeEvent = syntheticEvent.nativeEvent;
// Использовать нативные методы
console.log(nativeEvent.clientX); // координаты
nativeEvent.preventDefault(); // работает и в synthetic
nativeEvent.stopPropagation();
};
return <button onClick={handleClick}>Клик</button>;
}
Всплытие в React
Важно: синтетические события React всплывают, но иначе, чем нативные:
function Parent() {
return (
<div onClick={() => console.log('Parent')}>
<Child />
</div>
);
}
function Child() {
const handleClick = (e) => {
console.log('Child');
e.stopPropagation(); // Останавливает всплытие в React
};
return <button onClick={handleClick}>Клик</button>;
}
// При клике выведет: Child (Parent не выведется)
На практике: когда это важно
Проблема: Если слушать нативное событие и React событие вместе:
function Component() {
useEffect(() => {
// Нативный слушатель
const handleNativeClick = () => console.log('Native');
document.addEventListener('click', handleNativeClick);
return () => document.removeEventListener('click', handleNativeClick);
}, []);
// React событие
const handleReactClick = () => console.log('React');
return <button onClick={handleReactClick}>Клик</button>;
// Выведет: React, потом Native (из-за фазы всплытия)
}
Правильный подход: используй React события для обработки в компонентах:
function SearchInput() {
const [query, setQuery] = useState('');
const handleChange = (e) => {
setQuery(e.target.value); // Работает и в React
};
const handleSubmit = (e) => {
e.preventDefault(); // Работает
console.log(query);
};
return (
<form onSubmit={handleSubmit}>
<input onChange={handleChange} value={query} />
<button type="submit">Поиск</button>
</form>
);
}
Вывод
- DOM события - это нативная система JavaScript
- React события - это обёртка над DOM с делегированием на корень для оптимизации
- Большинство времени используешь React события (onClick, onChange, etc.)
- Нативные события нужны редко (например, слушание событий на window или document для специфических сценариев)
- React обеспечивает кроссбраузерную совместимость через SyntheticEvent