KuloDev
1 Hari
0 XP
advanced40 menitModul: 03-advanced-react-patterns

Optimasi Performa Render: React.memo, useMemo & useCallback

Kuasai strategi optimasi performa render di React: mencegah re-render yang tidak perlu dengan React.memo, caching kalkulasi berat dengan useMemo, dan referensial fungsi stabil dengan useCallback.

1. Mengapa Komponen React Melakukan Re-render?

Secara default, saat sebuah komponen induk (Parent) melakukan re-render karena perubahan state, **seluruh komponen anak (Children) di bawahnya akan ikut di-render ulang**, terlepas dari apakah props anak tersebut berubah atau tidak. Pada kebanyakan aplikasi kecil, re-render ini sangat cepat dan tidak bermasalah. Namun, pada pohon komponen besar atau kalkulasi data berat (seperti filter ribuan baris data), re-render berulang dapat menyebabkan lag pada antarmuka.

2. React.memo: Memoizing Komponen Presentasional

`React.memo` adalah Higher-Order Component (HOC) yang memeriksa apakah `props` komponen berubah menggunakan perbandingan dangkal (*shallow comparison* `===`). Jika props tidak berubah sejak render sebelumnya, React akan melompati proses render komponen tersebut.

example.js
javascript
1import React from 'react';
2
3const ExpensiveListItem = React.memo(function ExpensiveListItem({ title, onSelect }) {
4 console.log('Render:', title);
5 return <li onClick={onSelect}>{title}</li>;
6});
7
8export default ExpensiveListItem;

3. useMemo: Caching Hasil Komputasi Berat

`useMemo` menyimpan hasil eksekusi sebuah fungsi kalkulasi. Fungsi hanya akan dijalankan ulang ketika salah satu dependency di dalam array berubah.

example.js
javascript
1import { useState, useMemo } from 'react';
2
3function AnalyticsDashboard({ transactions }) {
4 const [filterType, setFilterType] = useState('ALL');
5
6 // Hanya dihitung ulang jika `transactions` atau `filterType` berubah
7 const totalVolume = useMemo(() => {
8 console.log('Menghitung total transaksi berat...');
9 return transactions
10 .filter(t => filterType === 'ALL' || t.type === filterType)
11 .reduce((sum, t) => sum + t.amount, 0);
12 }, [transactions, filterType]);
13
14 return <div>Total Volume: Rp {totalVolume.toLocaleString()}</div>;
15}

4. useCallback: Menjaga Stabilitas Referensi Fungsi

Di JavaScript, setiap kali sebuah fungsi di-deklarasikan ulang pada saat render, fungsi tersebut memiliki alamat memori baru (`() => {} !== () => {}`). Jika fungsi ini dipassing sebagai prop ke komponen yang dibungkus `React.memo`, memoization akan bocor (gagal) karena props dianggap selalu berubah. `useCallback` memastikan referensi fungsi tetap sama persis di antara render.

example.js
javascript
1import { useState, useCallback } from 'react';
2
3function ProductCatalog() {
4 const [count, setCount] = useState(0);
5
6 // handleDelete tidak akan dibuat ulang saat 'count' berubah
7 const handleDelete = useCallback((id) => {
8 console.log('Menghapus item:', id);
9 }, []);
10
11 return (
12 <div>
13 <button onClick={() => setCount(c => c + 1)}>Counter: {count}</button>
14 <ExpensiveListItem title="Item 1" onSelect={handleDelete} />
15 </div>
16 );
17}

Selesaikan Materi Ini?

Dapatkan +25 XP dan simpan progres belajarmu.