useLayoutEffect — useEffect dan farqi, qachon kerak
Muammo: miltillash (flicker)
Ba'zan komponent ekranda paydo bo'lganda bir lahza noto'g'ri joyda ko'rinadi, keyin to'g'ri joyga "sakraydi". Bu — miltillash. Foydalanuvchi buni sezadi.
Misol: tooltip yaratyapsiz. U bosgan elementning yonida paydo bo'lishi kerak. Lekin ekran chetiga yaqin bo'lsa — chapga siljishi kerak. Buning uchun tooltip ning o'lchamini o'lchab, pozitsiyasini hisoblash kerak.
useEffect bilan:
1. Tooltip ekranda paydo bo'ldi (noto'g'ri joyda)
2. Foydalanuvchi bir lahza noto'g'ri joyni ko'rdi ← miltillash
3. useEffect ishladi — pozitsiya hisoblandi
4. Tooltip to'g'ri joyga ko'chdi
useLayoutEffect bilan:
1. DOM yangilandi (tooltip hali ko'rinmaydi)
2. useLayoutEffect ishladi — pozitsiya hisoblandi
3. Tooltip to'g'ridan-to'g'ri to'g'ri joyda paydo bo'ldi ← miltillash yo'q
Farq: qachon ishlaydi?
Render jarayoni:
JSX hisoblandi
│
▼
DOM yangilandi
│
├── useLayoutEffect ishlaydi ← brauzer chizishdan OLDIN
│
▼
Brauzer ekranda chizadi ← foydalanuvchi ko'radi
│
▼
useEffect ishlaydi
useLayoutEffect — DOM tayyor, lekin foydalanuvchi hali ko'rmagan paytda ishlaydi. Shu paytda DOM ni o'zgartirsangiz — foydalanuvchi faqat yakuniy natijani ko'radi.
Amaliy misol — tooltip
function Tooltip({ matn, children }) {
const tooltipRef = useRef(null);
const [chap, setChap] = useState(0);
useLayoutEffect(() => {
const tooltip = tooltipRef.current;
const rect = tooltip.getBoundingClientRect();
// Ekranning o'ng chetidan chiqib ketayaptimi?
if (rect.right > window.innerWidth) {
// Chapga siljit
setChap(window.innerWidth - rect.width - 8);
}
}, []);
return (
<div style={{ position: 'relative', display: 'inline-block' }}>
{children}
<div
ref={tooltipRef}
style={{
position: 'absolute',
top: '100%',
left: chap,
background: '#333',
color: '#fff',
padding: '4px 8px',
borderRadius: '4px',
whiteSpace: 'nowrap',
}}
>
{matn}
</div>
</div>
);
}
Bu yerda useEffect ishlatilsa — tooltip avval o'ng tomonda paydo bo'lib, keyin chapga sakrardi. useLayoutEffect bilan — to'g'ridan-to'g'ri to'g'ri joyda paydo bo'ladi.
Qoida
useEffect → 99% holat uchun
useLayoutEffect → DOM o'lchamini o'qib, darhol o'zgartirish kerak bo'lganda
⚠️
useLayoutEffectsinxron ishlaydi — brauzer chizishni kutadi. Ichida og'ir ish qilsangiz — sahifa "qotib" qoladi. Faqat DOM o'lchash va pozitsiya hisoblash uchun ishlating.
Xulosa
useEffect: DOM → brauzer chizdi → effect ishladi
useLayoutEffect: DOM → effect ishladi → brauzer chizdi
Miltillash ko'rinmasa — useEffect ishlating. Tooltip, dropdown, popover kabi elementlar noto'g'ri joyda paydo bo'lib sakrasa — useLayoutEffect.
Keyingi dars
23-dars: useId — unique ID yaratish, accessibility uchun