Перейти к содержимому
На этой странице

События в JavaScript и React

Все темы React Developer

Подтемы:

Что такое распространение события (Event Propagation)?

Event Propagation — это механизм, определяющий порядок, в котором события обрабатываются в DOM-дереве.

Основные фазы:

  1. Погружение (Capturing):

    • Событие начинается с корневого элемента и проходит вниз до целевого элемента.

    • Пример:

      element.addEventListener('click', handler, true); // true - использовать фазу погружения
  2. Целевой элемент (Target):

    • Событие достигает целевого элемента и обрабатывается.
  3. Всплытие (Bubbling):

    • Событие поднимается обратно вверх по дереву от целевого элемента к корневому.

    • Пример:

      element.addEventListener('click', handler); // По умолчанию false - использовать фазу всплытия

Что такое всплытие события (Event Bubbling)?

Event Bubbling — это процесс, при котором событие, сначала обработанное целевым элементом, поднимается вверх по DOM-дереву, вызывая обработчики событий на каждом из родительских элементов.

Основные характеристики:

  1. Порядок обработки:

    • Событие сначала обрабатывается целевым элементом.

    • Затем поднимается (всплывает) к его родительским элементам и далее к корневому элементу.

  2. Пример:

    document.getElementById("child").addEventListener("click", function() {
        console.log("Child clicked");
    });
    
    document.getElementById("parent").addEventListener("click", function() {
        console.log("Parent clicked");
    });
    
    // При клике на элемент с id "child" сначала будет выведено "Child clicked", затем "Parent clicked"

Всплытие события позволяет обработчикам событий на родительских элементах реагировать на события, которые произошли на их потомках, начиная с целевого элемента и поднимаясь вверх по DOM-дереву.


Что такое погружение события (Event Capturing)?

Event Capturing — это фаза распространения события в DOM, при которой событие проходит сверху вниз от корневого элемента к целевому элементу.

Основные характеристики:

  1. Порядок обработки:

    • Событие сначала проходит через корневой элемент и спускается к целевому элементу, обрабатываясь на каждом уровне.
  2. Включение захвата:

    • Для использования фазы погружения необходимо установить третий параметр в true при добавлении обработчика событий.

    • Пример:

      document.getElementById("parent").addEventListener("click", function() {
          console.log("Parent clicked");
      }, true);
      
      document.getElementById("child").addEventListener("click", function() {
          console.log("Child clicked");
      }, true);

Погружение события позволяет обрабатывать события, начиная с корневого элемента и спускаясь вниз к целевому элементу, до того как событие достигнет целевого элемента.


Что такое event.target?

event.target указывает на элемент, на котором событие возникло изначально. При всплытии обработчик может находиться на родителе, а target всё равно укажет на вложенный элемент, по которому кликнули.

list.addEventListener("click", (event) => {
  console.log(event.target);
});

Не путайте его с event.currentTarget: тот указывает на элемент, чей обработчик сейчас выполняется. Документация MDN.


Что такое event.currentTarget?

event.currentTarget указывает на элемент, на котором зарегистрирован обработчик, выполняющийся сейчас. При всплытии он может отличаться от event.target, где событие возникло.

list.addEventListener("click", (event) => {
  console.log(event.target); // элемент, по которому кликнули
  console.log(event.currentTarget); // list
});

Вне обработчика currentTarget обычно равен null. Документация MDN.


Как обрабатывать события в React?

В React обработка событий происходит с использованием синтаксиса, аналогичного обработке событий в нативном JavaScript, но с некоторыми отличиями. Вот как обрабатывать события в React:

  1. Создание метода обработки события: Создайте метод внутри компонента, который будет выполняться при возникновении события. Название метода обычно начинается с префикса “handle”, за которым следует имя события или описательное имя.

  2. Привязка метода к элементу: Привяжите созданный метод к элементу, который будет генерировать событие. Это делается с помощью JSX, указав метод как значение атрибута события.

  3. Использование аргументов: Внутри метода обработки события вы можете получить доступ к объекту события и использовать его свойства, такие как target, чтобы получить информацию о событии.

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

import React, { Component } from "react";

class Button extends Component {
  handleClick = () => {
    console.log("Кнопка была нажата");
  };

  render() {
    return <button onClick={this.handleClick}>Нажми меня</button>;
  }
}

export default Button;

В этом примере метод handleClick вызывается при клике на кнопку, выводя сообщение в консоль.

Важно заметить, что при передаче метода обработки события в качестве атрибута JSX, не следует вызывать его с помощью круглых скобок (например, не пишите onClick={this.handleClick()}), так как это вызовет выполнение метода сразу при рендеринге.


Что такое синтетические события (synthetic events) в React?

В React, “синтетические события” (synthetic events) - это система обработки событий, которая предоставляет кросс-браузерную и кросс-платформенную абстракцию над нативными событиями браузера. Они создаются и управляются React и обеспечивают более единообразное поведение обработки событий в различных браузерах.

Синтетические события предоставляются компонентам React как аргументы обработчиков событий и имеют схожий интерфейс с нативными событиями браузера, но с некоторыми различиями и улучшениями.

Пример использования синтетических событий:

import React from "react";

class Button extends React.Component {
  handleClick = (event) => {
    event.preventDefault();
    console.log("Button clicked!");
  };

  render() {
    return <button onClick={this.handleClick}>Click me</button>;
  }
}

В этом примере, event является синтетическим событием, передаваемым в обработчик handleClick. Вы можете вызывать методы такие как preventDefault(), stopPropagation(), и другие, а также получать информацию о событии (например, event.target, event.clientX, и др.).

Синтетические события нормализуют интерфейс событий разных браузеров. В React DOM начиная с React 17 пулинг событий отключён, поэтому event.persist() для сохранения события не нужен.


Как реализовать drag-and-drop функциональность в React-приложении?

Реализация функциональности перетаскивания (drag-and-drop) в React-приложении может быть достигнута с использованием стандартных событий мыши и состояния компонентов React. Вот базовый подход к созданию такой функциональности:

  1. Создание компонентов для перетаскиваемых и целевых элементов:

     Сначала создайте компоненты для элементов, которые вы хотите перемещать (перетаскиваемые элементы) и элементов, на которые вы хотите перетащить (целевые области).

  2. Управление состоянием: Добавьте состояние в компоненты, чтобы отслеживать, перетаскивается ли в данный момент элемент или нет. Например, вы можете использовать useState для этого.

  3. Обработка событий: В компонентах перетаскиваемых элементов, добавьте обработчики событий onDragStart,  onDrag, и onDragEnd:

    <div draggable onDragStart="{(e)" ="">
      handleDragStart(e, item)} onDrag={(e) => handleDrag(e)} onDragEnd={(e) =>
      handleDragEnd(e)} > {/* Содержимое перетаскиваемого элемента */}
    </div>
  4. Реализация функций обработчиков: Создайте функции обработчики для событий перетаскивания. В них вы будете обновлять состояние компонентов и манипулировать данными о перетаскиваемом элементе.

  5. Определение областей для перетаскивания: В целевых компонентах определите зоны, на которые можно бросить перетаскиваемый элемент. Добавьте обработчики событий onDragOver и  onDrop:

    <div onDragOver="{(e)" ="">
      handleDragOver(e)} onDrop={(e) => handleDrop(e, target)} > {/* Содержимое
      целевой области */}
    </div>
  6. Реализация обработчиков для областей перетаскивания:  Аналогично создайте функции обработчики для событий onDragOver  и onDrop, где вы будете предотвращать стандартное поведение браузера и обновлять состояние компонентов в соответствии с действиями пользователя.

  7. Обновление состояния: В функциях обработчиках обновляйте состояние компонентов так, чтобы отражать текущее состояние перетаскивания.

  8. Рендеринг компонентов: Не забудьте рендерить ваши компоненты в компоненте верхнего уровня, чтобы создать интерфейс перетаскивания.

Приведенный выше подход представляет базовую концепцию реализации drag-and-drop в React. В более сложных случаях, например, при необходимости поддержки перетаскивания между разными компонентами или списками, возможно потребуется использовать дополнительные библиотеки или углубиться в более сложные паттерны.


Как реализовать перетаскивание (drag-and-drop) элементов в React-приложении?

Для реализации перетаскивания элементов в React-приложении вы можете использовать нативные события браузера в сочетании с состоянием компонентов React. Вот базовые шаги, как это можно сделать:

  1. Создание компонентов:
    • Создайте компоненты, которые вы планируете перемещать.

    • Определите обработчики событий для начала и завершения перетаскивания.

  2. Управление состоянием:
    • Создайте состояние, которое будет хранить информацию о перетаскиваемом элементе, его начальных координатах и т.д.
  3. Добавление обработчиков событий:
    • Добавьте обработчик события onDragStart для элемента, который будет перетаскиваться. В этом обработчике установите данные о перетаскиваемом элементе в состояние, используя функцию setData и event.dataTransfer.

    • Добавьте обработчики onDragOver и onDrop для контейнера, куда вы собираетесь перемещать элементы. В обработчике onDragOver предотвратите действие по умолчанию, чтобы разрешить перетаскивание, и в обработчике onDrop обработайте перетаскивание элемента.

Пример:

import React, { useState } from "react";

function DraggableElement({ text }) {
  const handleDragStart = (event) => {
    event.dataTransfer.setData("text/plain", text);
  };

  return (
    <div draggable onDragStart={handleDragStart} className="draggable-element">
      {text}
    </div>
  );
}

function DroppableArea() {
  const [droppedItems, setDroppedItems] = useState([]);

  const handleDragOver = (event) => {
    event.preventDefault();
  };

  const handleDrop = (event) => {
    event.preventDefault();
    const droppedText = event.dataTransfer.getData("text/plain");
    setDroppedItems([...droppedItems, droppedText]);
  };

  return (
    <div
      className="droppable-area"
      onDragOver={handleDragOver}
      onDrop={handleDrop}
    >
      {droppedItems.map((item, index) => (
        <div key={index}>{item}</div>
      ))}
    </div>
  );
}

function App() {
  return (
    <div className="app">
      <DraggableElement text="Перетащи меня!" />
      <DroppableArea />
    </div>
  );
}

export default App;

В чем разница между методами event.preventDefault() и event.stopPropagation()?

Разница между event.preventDefault() и event.stopPropagation():

  1. event.preventDefault():

    • Назначение: Предотвращает стандартное поведение браузера для события.

    • Пример:

      document.getElementById("myLink").addEventListener("click", function(event) {
          event.preventDefault(); // Отменяет переход по ссылке
      });
  2. event.stopPropagation():

    • Назначение: Останавливает дальнейшее распространение события (всплытие или погружение).

    • Пример:

      document.getElementById("child").addEventListener("click", function(event) {
          event.stopPropagation(); // Останавливает всплытие события
      });

Итог:

  • event.preventDefault(): Отменяет стандартное поведение события.

  • event.stopPropagation(): Останавливает распространение события по DOM-дереву.


Как узнать об использовании метода event.preventDefault()?

event.defaultPrevented показывает, была ли успешно отменена стандартная обработка события. Вызов preventDefault() не меняет это свойство, если событие неотменяемое или обработчик passive.

Пример использования:

document.getElementById("myLink").addEventListener("click", function (event) {
  event.preventDefault();
  console.log(event.defaultPrevented); // true
});

event.defaultPrevented показывает, была ли успешно отменена стандартная обработка события. Вызов preventDefault() не меняет это свойство, если событие неотменяемое или обработчик passive.

Собеседования: React

Смотри записи интервью, узнай, какие вопросы задают и как отвечают кандидаты.

Вопросы и ответы

Не нашли ответ? Напишите мне в чат. Я делаю Шпаргалку и сам отвечаю на сообщения. Расскажите, что не работает или чего вам не хватает. Может, смогу сразу взять это в работу.

Откуда взяты вопросы?

Из реальных собеседований. Основой подборки стал опыт Вадима Новосёлова: он проходил интервью и записывал вопросы. Подробнее о материалах.

Насколько эти вопросы актуальны?

Эти вопросы встречались нам на реальных собеседованиях в 2025 году. Мы регулярно проходим собеседования и пополняем подборку новыми вопросами. Основы профессии и ключевые технологии остаются востребованными годами, а детали конкретных инструментов и версий стоит сверять с текущей документацией.

На какой уровень рассчитана подборка?

Мы проходили собеседования на вакансии уровня Middle+, а иногда и на Senior-позиции. Вопросы из этих интервью вошли в подборку. Направления работы: React-разработчик, Frontend-разработчик. Глубина обсуждения зависит от вакансии: будь готов объяснить основную идею, привести практический пример и разобрать ограничения и альтернативы решения.

Этот вопрос точно будет на моём собеседовании?

Гарантии нет: набор вопросов зависит от компании, задач команды, уровня вакансии и самого интервьюера. Эти вопросы уже встречались на реальных собеседованиях, но на твоём интервью ту же тему могут проверить другой формулировкой, практической задачей или обсуждением твоего опыта. Используй подборку, чтобы разобраться в теме: объясняй идею своими словами, приводи примеры и готовься обсудить ограничения и альтернативы решения. Так будет проще ответить и на знакомый вопрос, и на неожиданные уточнения.