useEffect vs useLayoutEffect: краткое и понятное объяснение

Если ваша логика внутри useEffect должна отработать до отрисовки браузера - используйте useLayoutEffect. В противном случае вам подойдет useEffect.
useEffect
Он выполняется уже после рендера и подойдет в 99% процентах случаев.
Результат работы кода выше: отобразиться сначала old value
, через 3 секунды оно заменится на updated value
.
useLayoutEffect
Выполняется до отрисовки страницы. Например, если мы хотим изменить DOM с помощью рефа:
Результат работы кода выше: белый экран в течение 3 секунд, после чего сразу отобразиться updated value
.
Если бы мы использовали useEffect, то наш DOM-элемент изменился бы после первой отрисовки и мы бы заметили мерцание интерфейса.
Очень часто useLayoutEffect и useIsomorphicLayoutEffect (версия для серверного рендеринга) используются в различных React-библиотеках, например, в effector-react, так как стор хранится в рефе и его обновление должно происходить до первого рендера.
Почему такое происходит?
Представьте ситуацию, при которой в useEffect выполняется ресурсоемкая задача, ждать ее выполнения перед отрисовкой будет не совсем эффективно в большинстве случаев, необходимо показывать пользователю интерфейс как можно раньше. Поэтому React не ждет выполнения useEffect, а сразу показывает результат первого рендера на экране. Ранее в классовых компонентах componentDidMount и componentDidUpdate повторяли логику useLayoutEffect, из-за чего интерфейс пользователю мог показываться не сразу. В этом плане разработчики React провели правильную оптимизацию, а для тех, кому все еще нужно старое поведение, оставили useLayoutEffect и useIsomorphicLayoutEffect.