Работа мечты в один клик 💼

💭Мечтаешь работать в Сбере, но не хочешь проходить десять кругов HR-собеседований? Теперь это проще, чем когда-либо!
💡AI-интервью за 15 минут – и ты уже на шаг ближе к своей новой работе.
Как получить оффер?
📌 Зарегистрируйся
📌 Пройди AI-интервью
📌 Получи обратную связь сразу же!
HR больше не тянут время – рекрутеры свяжутся с тобой в течение двух дней! 🚀
Реклама. ПАО СБЕРБАНК, ИНН 7707083893. Erid 2VtzquscAwp
Перевод публикуется с сокращениями, автор оригинальной статьи Stefan Metodiev.

Если вы участвовали в проектах на JavaScript в качестве фронтенд/бекенд разработчика, то вы должны быть хорошо знакомы с прикреплением событий к документу, элементу или объекту окна через встроенный модуль событий.
React создает уровень абстракции над основным модулем JavaScript, чтобы предоставить оболочку событий (Synthetic Event wrapper), с помощью которой можно получить доступ к элементам Virtual DOM и манипулировать ими. В большинстве случаев это все, что нужно для передачи функции одному из Synthetic Event обработчиков.
Статья поможет понять:
- как правильно добавлять, очищать и отслеживать слушателей событий;
- как строить стратегии производительности и оптимизации слушателей;
- зачем необходимо создавать пользовательские event listener;
- для чего использовать традиционные и “реактивные” реализации.
1. Как правильно добавлять, очищать и отслеживать слушателей
Прежде, чем погрузиться в код и реализацию, давайте проясним процесс добавления событий в React и JavaScript. Мы можем добавить слушателя в объекты окна, документы или элемент в коде.
В любом случае лучше прикреплять таких слушателей на этапе монтирования компонента во избежание любого неожиданного поведения.
Вот как это делается в функциональном компоненте:
React.useEffect(() > {
document.addEventListener(‘click’, addIngredientHandler);
return ():void > document.removeEventListener(‘click’, addIngredientHandler)
}, [])
Очень важно очистить и удалить слушателя после того, как он перестанет быть нужен, а это произойдет, когда компонент размонтируется. Если мы оставим слушателей болтаться без очистки, могут возникнуть серьезные проблемы с производительностью приложения.
Еще один способ убедиться, что слушатели находятся в нужных местах или успешно удалены – проверять их и контролировать. Сделать это можно в Chrome Dev Tools:

Когда мы открываем инструменты разработчика и переходим к некоему элементу (в нашем случае – к документу) можно видеть, что EventListener прикреплен к DOM, ожидая выполнения.
Поскольку в статье используется codesandbox, можно заметить дополнительных слушателей в списке ниже. Так все выглядело бы во вкладке Event Listeners при наличии нескольких слушателей на объектах window, document и element:

Если внимательно посмотреть на последний скриншот, можно увидеть события “contextmenu” и “auxclick”, добавленные из codesandbox в глобальное пространство имен событий.
2. Стратегии производительности и оптимизации
Еще раз подчеркнем, что во избежание каких-либо проблем со слушателями событий нужно правильно добавлять (на этапе монтажа компонента) и очищать их.
Когда мы понимаем, как наблюдать за слушателями, следует убедиться, что они настроены на оптимальную производительность.
В методе addEventListener есть третий аргумент, позволяющий указывать дополнительные параметры, такие, как свойство once:
React.useEffect(() > {
document.addEventListener(‘click’, addIngreientsHandler, {
once: true
});
}, [])
- once
Свойство указывает, что listener должен быть вызван не более одного раза после добавления. Если оно принимает логическое значение true, то listener будет автоматически удален при вызове. В документации говорится, что опция автоматически удаляется после запуска слушателя, поэтому не нужно беспокоиться о ее очистке.
Еще один очень удобный флаг – passive option. С его помощью можно значительно улучшить производительность listener и сократить время отклика элементов. Вот как это выглядит:
React.useEffect(() > {
document.addEventListener(‘click’, addIngreientsHandler, {
passive: true
});
}, [])
- passive
Логическое значение true сообщает, что указанная слушателем функция никогда не вызовет функцию preventDefault(). Если пассивный слушатель вызывает функцию preventDefault(), агент пользователя создаст предупреждение в консоли. Дополнительные сведения для изучения ключей можно найти в разделе улучшение производительности.
В качестве эксперимента автор проверяет производительность слушателя с опцией и без. При обычном слушателе время выполнения составляет примерно 164мс, а с passive option, время выполнения упало до 116мс – на 30% эффективнее.
3. Создание кастомных listener
React предоставляет нам набор событий, но иногда может понадобиться более гибкое решение: обработать сложную анимацию, пользовательское скролл-событие, вызывающее изменения UI, или попытаться избежать перекрытия событий click в глобальном пространстве имен.
Мы всегда можем создать собственные события:
const createCustomEvent = (eventName: string, additionalData: {[key: string]: string }): CustomEvent | null > {
if (window) {
return new CustomEvent(eventName, {
detail: {
additionalData
}
});
}
return null;
};
Разберем, что здесь происходит.
- Мы ожидаем, что в метод createCustomEvent будут переданы два параметра: имя события и любые дополнительные данные, находящиеся в параметре detail.
- Внутри тела метода мы проверяем, существует ли объект window. Если нет, событие не может быть присоединено, и мы вернем null. В ином случае вернем конструктор CustomEvent, создающий пользовательское событие и передающий любые данные внутрь объекта detail.
Большая часть работы сделана, но нам нужен еще один метод, который отправит созданное событие:
export const toggleSideDrawerHandler = (additionalData: {[key: string]: string }): void > {
const typeOfEvent = createCustomEvent(‘toggleDrawer’, additionalData);
document.dispatchEvent(typeOfEvent);
};
Теперь рассмотрим эту часть кода:
- Во-первых, скрипт ожидает получения параметра из toggleSideDrawerHandler, который позже будет передан с вызовом события.
- Во-вторых, вызывается метод createCustomEvent, которому передаются дополнительные данные и имя события.
- И последнее, созданное событие отправляется в toggleDrawer всякий раз, когда будет вызван этот метод.
Когда методы событий созданы, осталось использовать их в действии. Можно прикрепить метод toggleSideDrawerHandler к любому элементу, а он вызовет toggleDrawer. В песочнице находится весь код с рабочей реализацией рассмотренного примера.
4. Использование традиционных реализаций
Использование слушателей событий в React – не то, чем можно регулярно злоупотреблять. Лучше использовать предоставляемый React по умолчанию Synthetic Event.
Представим ситуацию, когда необходимо вызвать action на «другой стороне» приложения, а передача нашего метода невозможна или реализация глобального состояния была бы излишней. В этом случае использование Event Listener можно считать правильным выходом из ситуации.
Наслаждайтесь и счастливого взлома!
Комментарии