v19.2Latest

Лазейки

Некоторым вашим компонентам может потребоваться управление и синхронизация с системами вне React. Например, вам может понадобиться сфокусировать поле ввода с помощью API браузера, воспроизвести или поставить на паузу видеоплеер, реализованный без React, или подключиться и прослушивать сообщения с удалённого сервера. В этой главе вы узнаете о лазейках, которые позволяют вам «выйти за пределы» React и подключиться к внешним системам. Большая часть логики приложения и потока данных не должна зависеть от этих возможностей.

Ссылки на значения с помощью рефов

Когда вы хотите, чтобы компонент «запомнил» какую-то информацию, но не хотите, чтобы эта информациявызывала новые рендеры, вы можете использоватьреф:

Как и состояние, рефы сохраняются React между рендерами. Однако установка состояния вызывает повторный рендер компонента. Изменение рефа — нет! Вы можете получить доступ к текущему значению этого рефа через свойствоref.current.

Реф похож на секретный карман вашего компонента, который React не отслеживает. Например, вы можете использовать рефы для храненияидентификаторов таймаутов,DOM-элементови других объектов, которые не влияют на результат рендеринга компонента.

Готовы изучить эту тему?

ПрочитайтеСсылки на значения с помощью рефов, чтобы узнать, как использовать рефы для запоминания информации.

Читать далее

Манипулирование DOM с помощью рефов

React автоматически обновляет DOM в соответствии с результатом рендеринга, поэтому вашим компонентам обычно не нужно им манипулировать. Однако иногда вам может потребоваться доступ к DOM-элементам, управляемым React — например, чтобы сфокусировать узел, прокрутить к нему или измерить его размер и положение. В React нет встроенного способа делать это, поэтому вам понадобится реф на DOM-узел. Например, нажатие на кнопку сфокусирует поле ввода с помощью рефа:

Готовы изучить эту тему?

ПрочитайтеМанипулирование DOM с помощью рефов, чтобы узнать, как получить доступ к DOM-элементам, управляемым React.

Читать далее

Синхронизация с помощью эффектов

Некоторым компонентам необходимо синхронизироваться с внешними системами. Например, вам может потребоваться управлять компонентом, не основанным на React, в зависимости от состояния React, установить подключение к серверу или отправить аналитический лог, когда компонент появляется на экране. В отличие от обработчиков событий, которые позволяют обрабатывать определённые события,эффектыпозволяют выполнить некоторый код после рендеринга. Используйте их для синхронизации вашего компонента с системой вне React.

Нажмите «Воспроизвести/Пауза» несколько раз и посмотрите, как видеоплеер остаётся синхронизированным со значением пропсаisPlaying:

Многие Эффекты также «очищаются» после себя. Например, Эффект, который устанавливает соединение с сервером чата, должен возвращатьфункцию очистки, которая сообщает React, как отключить ваш компонент от этого сервера:

В режиме разработки React немедленно запустит и очистит ваш Эффект один дополнительный раз. Вот почему вы видите"✅ Connecting...", напечатанное дважды. Это гарантирует, что вы не забудете реализовать функцию очистки.

Готовы изучить эту тему?

ПрочтитеСинхронизация с помощью Эффектов, чтобы узнать, как синхронизировать компоненты с внешними системами.

Читать далее

Возможно, вам не нужен Эффект

Эффекты — это аварийный люк из парадигмы React. Они позволяют вам «выйти за пределы» React и синхронизировать ваши компоненты с какой-либо внешней системой. Если внешняя система не задействована (например, если вы хотите обновить состояние компонента при изменении некоторых пропсов или состояния), вам не нужен Эффект. Удаление ненужных Эффектов сделает ваш код более понятным, быстрым и менее подверженным ошибкам.

Есть два распространённых случая, когда Эффекты не нужны:

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

Например, вам не нужен Эффект для корректировки некоторого состояния на основе другого состояния:

Вместо этого вычисляйте как можно больше во время рендеринга:

Однаковам нужныЭффекты для синхронизации с внешними системами.

Готовы изучить эту тему?

ПрочтитеВозможно, вам не нужен Эффект, чтобы узнать, как удалить ненужные Эффекты.

Читать далее

Жизненный цикл реактивных эффектов

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

Этот Эффект зависит от значения пропсаroomId. Пропсы — этореактивные значения, что означает, что они могут меняться при повторном рендере. Обратите внимание, что Эффектпересинхронизируется(и переподключается к серверу), еслиroomIdизменится:

React предоставляет правило линтера для проверки правильности указания зависимостей вашего Эффекта. Если вы забудете указатьroomIdв списке зависимостей в приведённом выше примере, линтер автоматически обнаружит эту ошибку.

Готовы изучить эту тему?

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

Читать далее

Разделение событий и эффектов

Обработчики событий повторно выполняются только при повторном выполнении того же взаимодействия. В отличие от обработчиков событий, эффекты повторно синхронизируются, если какие-либо из прочитанных ими значений, такие как пропсы или состояние, отличаются от значений во время последнего рендера. Иногда требуется смесь обоих поведений: эффект, который повторно выполняется в ответ на изменение одних значений, но не других.

Весь код внутри эффектов являетсяреактивным.Он будет выполняться снова, если какое-либо реактивное значение, которое он читает, изменилось из-за повторного рендера. Например, этот эффект переподключится к чату, если изменитсяroomIdилиtheme:

Это не идеально. Вы хотите переподключаться к чату только при измененииroomId. Переключениеthemeне должно вызывать повторное подключение к чату! Вынесите код, читающийtheme, из вашего эффекта всобытие эффекта:

Код внутри событий эффекта не является реактивным, поэтому изменениеthemeбольше не вызывает повторного подключения вашего эффекта.

Готовы изучить эту тему?

ПрочтитеРазделение событий и эффектов, чтобы узнать, как предотвратить повторный запуск эффектов из-за некоторых значений.

Читать далее

Удаление зависимостей эффекта

Когда вы пишете эффект, линтер проверяет, что вы включили в список зависимостей эффекта каждое реактивное значение (например, пропсы и состояние), которое эффект читает. Это гарантирует, что ваш эффект остаётся синхронизированным с последними пропсами и состоянием вашего компонента. Лишние зависимости могут вызывать слишком частое выполнение эффекта или даже создавать бесконечный цикл. Способ их удаления зависит от случая.

Например, этот эффект зависит от объектаoptions, который заново создаётся каждый раз при редактировании ввода:

Вы не хотите, чтобы чат переподключался каждый раз, когда вы начинаете печатать сообщение. Чтобы исправить эту проблему, переместите создание объектаoptionsвнутрь эффекта, чтобы эффект зависел только от строкиroomId:

Обратите внимание, что вы не начали с редактирования списка зависимостей, чтобы удалить зависимость отoptions. Это было бы неправильно. Вместо этого вы изменили окружающий код так, что зависимость сталаненужной.Думайте о списке зависимостей как о списке всех реактивных значений, используемых в коде вашего эффекта. Вы не выбираете намеренно, что туда поместить. Этот список описывает ваш код. Чтобы изменить список зависимостей, измените код.

Готовы изучить эту тему?

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

Читать далее

Повторное использование логики с помощью пользовательских хуков

React поставляется со встроенными хуками, такими какuseState,useContext и useEffect. Иногда вам может хотеться, чтобы существовал хук для какой-то более конкретной цели: например, для получения данных, отслеживания состояния подключения пользователя к сети или подключения к чат-комнате. Для этого вы можете создавать собственные хуки под нужды вашего приложения.

В этом примере пользовательский хукusePointerPositionотслеживает позицию курсора, а пользовательский хукuseDelayedValueвозвращает значение, которое «отстаёт» от переданного вами значения на определённое количество миллисекунд. Проведите курсором по области предпросмотра песочницы, чтобы увидеть движущийся след из точек, следующих за курсором:

Вы можете создавать пользовательские хуки, комбинировать их, передавать данные между ними и повторно использовать их в разных компонентах. По мере роста вашего приложения вы будете писать меньше эффектов вручную, потому что сможете повторно использовать уже написанные пользовательские хуки. Также существует множество отличных пользовательских хуков, поддерживаемых сообществом React.

Готовы изучить эту тему?

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

Читать далее

Что дальше?

Перейдите к разделуСсылки на значения с помощью реф