Как фронтенд-разработчики, работающие с React, мы постоянно используем хук useEffect для рендеринга побочных эффектов.

Но знаете ли вы, что есть похожий, но немного другой хук под названием useLayoutEffect? Я этого не делал, пока не наткнулся на пример этого, использованный в одной из кодовых баз, в которых я участвовал.

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

Разница

В двух словах разница заключается в точности.

  • useEffect запускается, но нет никакой гарантии, когда именно это произойдет. Это асинхронная операция, которая выполняется после компоновки и рисования пикселей.
  • useLayoutEffect, напротив, гарантированно запускается немедленно. Это синхронная операция, которая происходит после всех изменений DOM и до того, как браузер сможет отрисовать пиксели. Если вы знакомы с жизненным циклом componentDidMount в компонентах класса React, это в основном эквивалентное поведение.

useLayoutEffect кажется лучше. Должны ли мы использовать его для всего?

Но почему, при прочих равных, мы не хотим использовать useLayoutEffect все время?

Не так быстро. Как и все остальное, точность имеет свою цену.

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

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

По словам официальных документов React в разделе Время эффектов:

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

Примечание: команда React недавно обновила useEffect в React 18, чтобы сделать его синхронным для общих событий, таких как клики пользователя, и еще меньше причин для использования хука useLayoutEffect.

Когда мы должны использовать useLayoutEffect ?

Итак, когда мы должны подумать об использовании этой мощной, но ущербной силы?

Обычно это сводится к одной основной причине: когда вам нужно измерить DOM и обеспечить немедленную визуальную обратную связь расчета (отсюда и «Макет» в названии). Это важно здесь, поскольку побочные эффекты не могут быть отложены.

Существует дополнительный вариант использования:

  • Как я упоминал выше, useLayoutEffect является эквивалентом старого жизненного цикла componentDidMount в компонентах класса React. Этот хук можно использовать, чтобы помочь вам перейти от компонентов класса к компонентам функций, чтобы получить замену один к одному. Однако это должно быть временным решением.

Выводы

Таким образом, в основном useEffect похож на вашу надежную Toyota Corolla: надежный, производительный и дешевый - идеально подходит для 99,9% случаев использования. useLayoutEffect, напротив, похож на высококлассный Ferrari: быстрый, отзывчивый, но дорогой, зарезервированный для 0,1%, когда скорость действительно имеет значение.

  • useEffect и useLayoutEffect используются для побочных эффектов, но последний позволяет более точно контролировать его работу.
  • Используйте useEffect как можно чаще, чтобы воспользоваться преимуществами оптимизации производительности команд React.
  • Существует очень мало реальных вариантов использования useLayoutEffect. Используйте только в том случае, если (1) вам нужно немедленно визуально показать побочные эффекты вашим пользователям или (2) когда вы временно переходите с componentDidMount .