useInsertionEffect Hook — CSS-in-JS գրադարանների օպտիմիզացում
useInsertionEffect-ը React-ի հատուկ hook է, որը հայտնվել է React 18-ում։ Այն նախատեսված է CSS-in-JS գրադարանների համար (օր. styled-components, Emotion, JSS և այլն)՝ ապահովելու, որ CSS style-ները ներարկվեն DOM-ի մեջ ճիշտ ժամանակին՝ մինչև rendering-ը։
Սա performance hook է, որը թույլ է տալիս React-ին կանխել “unstyled flash”-ը՝ երբ կոմպոնենտը երևում է էկրանին առանց իր CSS-ի և մի վայրկյան հետո նոր ձևավորվում։
🔹 Ինչպես է այն աշխատում
React-ի rendering ընթացքը կարելի է բաժանել երեք փուլերի․
- Render Phase — React-ը հաշվարկում է ինչ պետք է պատկերել (Virtual DOM):
- Commit Phase (before paint) — React-ը պատրաստվում է DOM-ը թարմացնել։
- Paint Phase — browser-ը ցուցադրում է փոփոխությունները էկրանին։
useInsertionEffect-ը աշխատում է հենց commit phase-ի սկզբում՝ նախքան React-ը կգրի DOM-ի փոփոխությունները, այսինքն՝ նախքան useLayoutEffect-ը։
📍 Երբ է պետք օգտագործել
- Եթե գրում ես CSS-in-JS գրադարան (օր. styled-components-ի նման)։
- Եթե ուզում ես ծրագրային եղանակով ներարկել CSS կամ ` <style> ` թեգեր՝ առանց flicker-ի։
- Եթե պետք է ապահովես, որ DOM-ի նոր էլեմենտները ունենան իրենց ճիշտ CSS-ը դեռ նախքան rendering-ը։
📍 Օրինակ 1 — Հիմնական կառուցվածք
Ահա թե ինչպես է hook-ը օգտագործվում React-ում․
import React, { useInsertionEffect } from 'react';
export default function StyledBox() {
useInsertionEffect(() => {
const style = document.createElement('style');
style.innerHTML = `
.styled-box {
background: linear-gradient(45deg, #2196f3, #21cbf3);
color: white;
padding: 20px;
border-radius: 8px;
transition: all 0.3s ease;
}
.styled-box:hover {
transform: scale(1.05);
}
`;
document.head.appendChild(style);
return () => {
document.head.removeChild(style);
};
}, []);
return <div className="styled-box">Beautiful styled box 💎</div>;
}
Այս օրինակում CSS-ը ներմուծվում է DOM-ի մեջ մինչև rendering-ը, այսինքն՝ երբ կոմպոնենտը render է լինում՝ այն արդեն ձևավորված է, առանց տեսանելի flicker-ի։
📍 Օրինակ 2 — Համեմատություն useEffect-ի հետ
Նայենք՝ ինչ տարբերություն կլինի, եթե նույն բանն անենք `useEffect`-ով instead of `useInsertionEffect`․
useEffect(() => {
const style = document.createElement('style');
style.innerHTML = '.red { color: red; }';
document.head.appendChild(style);
}, []);
Այս դեպքում style-ը կավելացվի միայն այն բանից հետո, երբ React-ը render անի կոմպոնենտը։ Դա նշանակում է՝ օգտվողը կարող է կես վայրկյան տեսնել անձև, չձևավորված UI (“unstyled flash”)։
useInsertionEffect-ը լուծում է հենց այս խնդիրը՝ CSS-ը ներմուծելով նախքան browser-ի paint-ը։
🧠 Երբ պետք չէ օգտագործել useInsertionEffect
Այս hook-ը նախատեսված չէ սովորական ծրագրավորողների համար։ Եթե դու չես գրում CSS-in-JS գրադարան կամ framework, շատ հավանական է՝ երբեք այն չպետք է կիրառես։
- Մի օգտագործիր network հարցումների կամ state-ի փոփոխությունների համար։
- Մի գրիր այստեղ async կոդ (fetch, timeout և այլն)։
- Մի ավելացրու մեծ DOM գործողություններ — դա կդանդաղեցնի rendering-ը։
⚙️ Տեխնիկական մանրամասներ
- Գործարկվում է նախքան useLayoutEffect-ը։
- Աշխատում է միայն client-side rendering-ի ժամանակ։
- Ստեղծված է հատուկ գրադարանների համար՝ CSS insertion-ը սինխրոն պահելու նպատակով։
Այս hook-ը ոչ մի արժեք չի վերադարձնում։ Այն միայն կատարում է “side effect”՝ օգնելով React-ին ներդնել CSS-ը ճիշտ ժամանակին։
🎯 Վարժություն (փորձիր ինքդ)
Գրիր կոմպոնենտ, որը․
- Օգտագործում է useInsertionEffect՝ ավելացնելու համար custom CSS style head-ի մեջ։
- Ցուցադրում է տեքստ, որը գունավորվում է այդ CSS-ով։
- Փորձիր նույն բանն անել useEffect-ով և նկատիր flicker տարբերությունը։
📘 Ամփոփում
- useInsertionEffect — React 18-ի hook է՝ նախատեսված CSS-in-JS գրադարանների համար։
- Գործարկվում է render-ից անմիջապես հետո, բայց մինչև DOM-ի paint-ը։
- Օգնում է խուսափել flicker-ից և ապահովում է consistent styling։
- Չպետք է օգտագործվի սովորական business logic-ի համար։