Sobes.tech
Назад к вопросам
Middle+
4

import React, { useState, useEffect, useLayoutEffect } from 'react'; export default () => { const [count, setCount] = useState(0); useLayoutEffect(() => console.log("each render 1")); console.log("each render 2"); useEffect(() => console.log("each render 3")); return ( <button onClick={() => setCount((prevProps) => ++prevProps)}> Increment </button> ); } // mount -> each render 2, each render 1, each render 3 // update -> each render 2, each render 1, each render 3 // unmount 4

Компании, где спрашивали
IT OneIT One

Ответ от нейросети

sobes.tech AI

В React порядок вызова и срабатывания хуков и логов следующий:

  • При каждом рендере сначала выполняется тело компонента, где вызывается console.log("each render 2").
  • Затем вызывается useLayoutEffect, который срабатывает синхронно сразу после изменения DOM, но до того, как браузер отрисует изменения. Там вызывается console.log("each render 1").
  • После того, как браузер отрисовал изменения, вызывается useEffect, где вызывается console.log("each render 3").

Таким образом, при монтировании и обновлении порядок логов будет:

each render 2
each render 1
each render 3

При размонтировании useEffect и useLayoutEffect могут возвращать функции очистки, но в данном примере их нет, поэтому логов при размонтировании нет.

Пример с пояснениями:

import React, { useState, useEffect, useLayoutEffect } from 'react';

export default () => {
  const [count, setCount] = useState(0);

  useLayoutEffect(() => {
    console.log("each render 1");
  });

  console.log("each render 2");

  useEffect(() => {
    console.log("each render 3");
  });

  return (
    <button onClick={() => setCount(prev => prev + 1)}>
      Increment
    </button>
  );
}

Важно: useLayoutEffect блокирует отрисовку до выполнения, а useEffect выполняется асинхронно после отрисовки.