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

import React, { useState, useEffect, useRef, useContext, useReducer, useMemo } 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 () => { console.log(4); }; }, [count]); return ( <button onClick={() => setCount((prevProps) => ++prevProps)}> Increment </button> ); }

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

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

sobes.tech AI

В данном React-компоненте происходит следующее:

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

    • Вызывается после всех изменений DOM, синхронно перед отображением браузером.
    • Выполняется после каждого рендера.
  2. console.log("each render 2");

    • Выполняется при каждом рендере компонента, в теле функции.
  3. useEffect(() => { ... }, [count]);

    • Выполняется после каждого изменения count.
    • При каждом изменении count сначала вызывается функция очистки (которая выводит 4), затем основной эффект (выводит "each render 3").
  4. Кнопка увеличивает count на 1 при клике.

Порядок логов при первом рендере:

  • "each render 2" (в теле компонента)
  • "each render 1" (useLayoutEffect)
  • "each render 3" (useEffect)

При изменении count:

  • "each render 2"
  • "each render 1"
  • "4" (функция очистки предыдущего эффекта)
  • "each render 3"

Обратите внимание, что useLayoutEffect вызывается синхронно после рендера, а useEffect — асинхронно после отрисовки.

Также стоит исправить инкремент в setCount: лучше использовать prev => prev + 1, а не ++prev, чтобы избежать побочных эффектов:

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