Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Prefer useEffect over useLayoutEffect by default
useLayoutEffect can block paint; reserve it for layout measurement that must run before paint.
Bad example
| 1 | import { useLayoutEffect, useState } from "react"; |
| 2 |
|
| 3 | export function StickyHeader() { |
| 4 | const [isCompact, setIsCompact] = useState(false); |
| 5 |
|
| 6 | useLayoutEffect(function onScrollLayout() { |
| 7 | const onScroll = () => { |
| 8 | setIsCompact(window.scrollY > 40); |
| 9 | }; |
| 10 |
|
| 11 | window.addEventListener("scroll", onScroll); |
| 12 | onScroll(); |
| 13 |
|
| 14 | return () => { |
| 15 | window.removeEventListener("scroll", onScroll); |
| 16 | }; |
| 17 | }, []); |
| 18 |
|
| 19 | return <header className={isCompact ? "compact" : ""}>Header</header>; |
| 20 | } |
Explanation (EN)
useLayoutEffect runs before paint and can contribute to jank if it does non-trivial work. For scroll listeners and simple state updates, useEffect is typically sufficient.
Objašnjenje (HR)
useLayoutEffect se izvrsava prije painta i moze uzrokovati jank ako radi nesto ne-trivijalno. Za scroll listenere i jednostavne state updateove, useEffect je obicno dovoljan.
Good example
| 1 | import { useEffect, useState } from "react"; |
| 2 |
|
| 3 | export function StickyHeader() { |
| 4 | const [isCompact, setIsCompact] = useState(false); |
| 5 |
|
| 6 | useEffect(function onScroll() { |
| 7 | const onScroll = () => { |
| 8 | setIsCompact(window.scrollY > 40); |
| 9 | }; |
| 10 |
|
| 11 | window.addEventListener("scroll", onScroll, { passive: true }); |
| 12 | onScroll(); |
| 13 |
|
| 14 | return () => { |
| 15 | window.removeEventListener("scroll", onScroll); |
| 16 | }; |
| 17 | }, []); |
| 18 |
|
| 19 | return <header className={isCompact ? "compact" : ""}>Header</header>; |
| 20 | } |
Explanation (EN)
useEffect schedules work after paint, reducing the risk of blocking rendering. UseLayoutEffect should be reserved for DOM measurements that must be synchronous.
Objašnjenje (HR)
useEffect radi nakon painta i smanjuje rizik blokiranja rendera. useLayoutEffect ostavi za DOM mjerenja koja moraju biti sinkrona.
Notes (EN)
If you must measure layout and immediately apply style changes to avoid flicker, useLayoutEffect is appropriate. Document why.
Bilješke (HR)
Ako moras mjeriti layout i odmah primijeniti stil da izbjegnes flicker, useLayoutEffect je opravdan. Dokumentiraj zasto.
Exceptions / Tradeoffs (EN)
useLayoutEffect is acceptable for reading layout (getBoundingClientRect) and synchronously applying changes that prevent a visible jump.
Iznimke / Tradeoffi (HR)
useLayoutEffect je prihvatljiv za citanje layouta (getBoundingClientRect) i sinkrono primjenjivanje promjena koje sprjecavaju vidljivi skok.