Владислав Калачев

Учим useLayoutEffect на примерах. Отличие хука useEffect от useLayoutEffect? — React Hooks

145

Доброго времени суток, друзья. Продолжаем цикл статей по теме React Hooks. Сегодня рассмотрим такой редко используемый хук как useLayoutEffect. На примере разберем, как и для чего его можно применять, а также поймем, чем отличается хук useEffect от useLayoutEffect.

Видео на эту тему.

Зачем нам useLayoutEffect?

Согласно официальной документации хук useLayoutEffect по своим параметрам (сигнатуре) полностью идентичен хуку useEffect. Главное же отличие заключается в том, что useLayoutEffect вызывается синхронно, после всех изменений в DOM. Также сами разработчики React рекомендуют использовать useLayoutEffect только в случае острой необходимости, чтобы вдруг не возникло проблем с правильным рендерингом компонентов. Хук useLayoutEffect можно использовать в случаях, когда необходимо произвести какие-то вычисления либо замеры в реальном DOM или провести синхронно мутацию (изменения).

Отличие хука useEffect от useLayoutEffect

Для примера создадим компонент, в котором будет состояние и div c выводом значения этого состояния. По клику на div будет происходить изменение состояния на значение равное 0. В дополнение к этой логике имеется хук useEffect, в котором при изменении зависимости их useState происходит повторный вызов функции изменения состояния setValue.

Пример:


import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";

const Component = () => {
  const [value, setValue] = useState(0);

  useEffect(() => {
    if (value === 0) {
      setValue(Math.random() * 99 + 99);
    }
  }, [value]);

  console.log("render", value);
  return <div onClick={() => setValue(0)}>value: {value}</div>;
};

ReactDOM.render(<Component />, document.querySelector(«#root»));

В данном примере после клика на значение можно увидеть небольшое мигание. Дело в том, что по умолчанию в setValue передается 0, а затем в хуке useEffect происходит повторный вызов данной функции с рандомным значением. Вызов useEffect происходит асинхронно, что приводит к последовательному рендеру компонента и как следствие миганию.

Давайте теперь заменим useEffect на useLayoutEffect.

Пример:


import React, { useState, useLayoutEffect } from "react";
import ReactDOM from "react-dom";

const Component = () => {
  const [value, setValue] = useState(0);

  useLayoutEffect(() => {
    if (value === 0) {
      setValue(Math.random() * 99 + 99);
    }
  }, [value]);

  console.log("render", value);
  return <div onClick={() => setValue(0)}>value: {value}</div>;
};

ReactDOM.render(<Component />, document.querySelector("#root"));

По клику на value теперь можно увидеть, что мигание пропало. Так как хук useLayoutEffect вызывается синхронно, то после вызова setValue с 0 сразу идет вызов setValue с рандомным значением. Благодаря хуку useLayoutEffect происходит «группировка» этих значений и как результат в DOM сразу попадает последнее в цепочке вызовов. Перерендеривание компонента происходит не последовательно, а одномоментно, тем самым исключая появление мигания.

Заключение

Сегодня мы рассмотрели на примере работу с хуком useLayoutEffect и разобрали в чем заключается его отличие от хука useEffect. Надеюсь, что данный материал был вам полезен. Учитесь, думайте, пишите код. Удачного кодинга, друзья!

Полезные материалы

Офф док: https://ru.reactjs.org/docs/hooks-reference.html#uselayouteffect

Подписывайтесь на наш канал в Telegram и на YouTube для получения самой последней и актуальной информации. 

+1

Комментарии:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *