Middle+
import React, { useState, useEffect, useLayoutEffect } from 'react'; export default () => { const [count, setCount] = useState(0); useLayoutEffect(() => console.log("minden renderelés 1")); console.log("minden renderelés 2"); useEffect(() => console.log("minden renderelés 3")); return ( <button onClick={() => setCount((prevProps) => ++prevProps)}> Növel </button> ); } // mount -> minden renderelés 2, minden renderelés 1, minden renderelés 3 // update -> minden renderelés 2, minden renderelés 1, minden renderelés 3 // unmount 4
sobes.tech MI
Válasz az MI-től
React-ben a hook-ok hívási és végrehajtási sorrendje a következő:
- Minden rendereléskor először a komponens törzse fut le, ahol a
console.log("each render 2")hívódik. - Ezután a
useLayoutEffectkerül meghívásra, amely szinkron módon fut le közvetlenül a DOM módosítása után, de még azelőtt, hogy a böngésző megrajzolná a változásokat. Itt aconsole.log("each render 1")kerül meghívásra. - Miután a böngésző megrajzolta a változásokat, a
useEffectkerül meghívásra, ahol aconsole.log("each render 3")fut le.
Így a komponens mountolásakor és frissítésekor a logok sorrendje:
each render 2
each render 1
each render 3
A komponens leválasztásakor a useEffect és useLayoutEffect visszatérhetnek tisztító függvényekkel, de ebben a példában nincsenek, így leválasztáskor nem lesz log.
Példa magyarázattal:
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>
);
}
Fontos: A useLayoutEffect blokkolja a renderelést a végrehajtásáig, míg a useEffect aszinkron módon fut a renderelés után.