Kaskade re-render React: ketika satu klik me-render ulang seluruh pohon
Apa yang terjadi
Di React, pembaruan state me-render ulang komponen dan, secara default, semua anaknya. Jika state berada di atas pohon (sebuah context, store tingkat halaman), satu ketukan atau klik bisa me-render ulang ratusan komponen — yang sebagian besar menampilkan persis hal yang sama seperti sebelumnya.
Setiap render murah; ribuan render dalam satu handler tidak. Pekerjaannya jatuh pada fase processing time INP.
Cara mengenali
- Profiler React DevTools menampilkan flame graph lebar: komponen me-render ulang tanpa props-nya berubah secara terlihat.
- Mengetik pada input terkontrol tersendat; setiap ketukan me-render ulang daftar atau tabel besar.
- Processing time mendominasi INP, dan stack di DevTools Performance penuh dengan internals React.
Cara memperbaiki
- Turunkan state: simpan di komponen terkecil yang membutuhkannya alih-alih komponen tingkat halaman atau context.
- Bungkus subtree yang mahal dengan React.memo dan stabilkan props yang Anda kirim dengan useCallback/useMemo — memo tidak berguna jika callback baru dibuat pada setiap render.
- Tandai pembaruan tidak mendesak (memfilter daftar saat mengetik) dengan useTransition agar render mendesak (input itu sendiri) dilukis lebih dulu.
Masalah
const Page = () => {
const [query, setQuery] = useState("")
// every keystroke re-renders Page → Header, Sidebar, BigTable, Footer
return <>
<SearchInput value={query} onChange={setQuery} />
<BigTable rows={filterRows(rows, query)} />
</>
}
Perbaikan
const BigTable = React.memo(({ rows }) => /* ... */)
const Page = () => {
const [query, setQuery] = useState("")
const [isPending, startTransition] = useTransition()
const rows = useMemo(() => filterRows(allRows, query), [query])
const onChange = (q) =>
startTransition(() => setQuery(q)) // input paints first, table follows
return <>
<SearchInput onChange={onChange} />
<BigTable rows={rows} />
</>
}
Pindai situs Anda gratis →