← Назад к вопросам

В чем разница работы Event в React и в DOM?

2.0 Middle🔥 301 комментариев
#React

Комментарии (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:

  1. Capturing (захват) - событие идёт от window к целевому элементу
  2. Target (целевой элемент) - событие на самом элементе
  3. 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 обрабатывает события:

  1. React не добавляет слушателей к каждому элементу
  2. Вместо этого добавляет один слушатель к корню документа (или контейнеру)
  3. Использует делегирование событий для обработки
  4. При клике обходит компоненты и вызывает нужные обработчики
// Так React работает внутри (упрощённо)
const root = document.getElementById('root');

root.addEventListener('click', (nativeEvent) => {
  // React обходит дерево компонентов
  // и вызывает обработчики onClick
  const handlers = findHandlersInTree(nativeEvent.target);
  handlers.forEach(handler => handler(syntheticEvent));
});

Ключевые отличия

АспектНативный DOMReact
Способ подпискиaddEventListenerАтрибуты вроде onClick
Полинг событийНа каждом элементеДелегирование на корень
Объект событияНативный EventSyntheticEvent (обёртка)
ПроизводительностьМожет быть медленным для больших списковОптимизировано через делегирование
Доступ к нативному 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
В чем разница работы Event в React и в DOM? | PrepBro