Back to questions
IT One
Middle+
5
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
Companies where asked
Answer from AI
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 выполняется асинхронно после отрисовки.