Hook Optimasi Performa useCallback di React
Dalam pelajaran ini, kita akan membahas hook berikutnya
untuk optimasi performa
useCallback.
Hook useCallback mirip dengan API useMemo,
perbedaannya terletak pada yang pertama
menyimpan nilai dalam cache di antara momen render ulang
layar, sedangkan yang kedua - callback.
Ini memungkinkan kita untuk tidak menjalankan ulang
fungsi yang memakan sumber daya
ketika tidak diperlukan dan dapat
digunakan saat
meneruskan fungsi
ke komponen anak.
Mari kita pahami lebih detail dengan contoh.
Pertama-tama, buat komponen App
dan buat state num di dalamnya:
const [num, setNum] = useState(0);
Misalkan kita memiliki tombol, yang saat diklik
num akan bertambah
sebesar 1, dan paragraf, di mana kita
akan menampilkan nilai num:
return (
<div>
<button onClick={() => setNum(num + 1)}>klik</button>
<p>klik: {num}</p>
</div>
);
Sekarang, anggap dalam
App ditampilkan juga daftar tertentu
dengan elemen, yang akan kita tambahkan
dengan menekan tombol lain. Untuk menyimpan
elemen daftar ini, kita akan buat
state items:
const [items, setItems] = useState([]);
Kemudian tulis fungsi addItem
untuk menambahkannya:
function addItem() {
setItems([...items, 'item baru']);
}
Sekarang mari tulis kode untuk menampilkan
elemen daftar dan pindahkan ke komponen anak
Items, yang melalui props
akan menerima array elemen
dan fungsi untuk menambahkannya. Jangan lupa
menambahkan output ke konsol, untuk melihat
kapan Items kita akan
di-render ulang:
function Items({ items, addItem }) {
const result = items.map((item, index) => {
return <p key={index}>{item}</p>;
});
console.log('Items render');
return (
<div>
<h3>Item kami</h3>
{result}
<button onClick={addItem}>tambah item</button>
</div>
);
}
export default Items;
Letakkan Items di akhir komponen
App dan teruskan array
items dan fungsi untuk menambahkan
elemen addItem ke dalamnya:
return (
<>
<div>
<button onClick={() => setNum(num + 1)}>klik</button>
<p>klik: {num}</p>
<br />
</div>
<Items items={items} addItem={addItem} />
</>
);
Sekarang coba klik tombol-tombolnya
dan pastikan bahwa num bertambah dan
elemen baru ditambahkan ke daftar.
Dengan membuka konsol, kita akan melihat bahwa
daftar kita di-render ulang setiap
saat, bahkan jika kita mengklik tombol,
yang menambah num.
Jika daftar kita kecil, maka tidak masalah,
tapi bagaimana jika diasumsikan daftarnya
akan besar dan ada banyak hal lain di sana?
Bukan masalah - Anda akan berkata, karena pada pelajaran
sebelumnya kita telah membahas API memo,
untuk menghindari render ulang komponen
yang tidak perlu.
Jadi mari bungkus komponen kita
Items dengan memo dan selesai.
Omong-omong, ini bisa dilakukan langsung
saat mengekspor Items:
export default memo(Items);
Jangan lupa untuk mengimpor memo:
import { memo } from 'react';
Sekarang buka konsol dan klik
tombol-tombolnya. Semua usaha sia-sia! Kita
telah memoisasi komponen, tetapi saat menekan
tombol 'klik' komponen
Items tetap
di-render ulang setiap kali.
Masalahnya adalah ketika komponen induk
di-render ulang, fungsinya
dibuat ulang - ini juga berlaku untuk
fungsi addItem kita, yang kita teruskan ke
Items.
Tepat pada momen inilah hook
useCallback akan membantu kita. Mari terapkan
hook tersebut. Pertama-tama, impor ke
App:
import { useCallback } from 'react';
Kemudian ubah deklarasi fungsi sederhana
addItem menjadi
Ekspresi Fungsi, tentukan sebagai
parameter pertama untuk useCallback
fungsi kita dalam bentuk callback. Parameter kedua
dalam kurung siku tentukan
dependensi - semua variabel reaktif
yang terlibat dalam fungsi, dalam kasus kita
ini adalah array items:
const addItem = useCallback(() => {
setItems(() => [...items, 'Item Baru']);
}, [items]);
Selesai! Dengan demikian, kita telah menyimpan
fungsi dalam cache. Klik lagi tombol-tombolnya dan
lihat bahwa sekarang saat menekan tombol
'klik' komponen anak kita tidak
di-render ulang.
Buat komponen App, tempatkan
paragraf dengan teks di dalamnya. Buat
state dengan nilai awal 'teks'
dan tampilkan nilainya di paragraf. Misalkan saat diklik
pada paragraf, di akhir teksnya
ditambahkan tanda seru.
Buat komponen anak Products,
di mana Anda akan memiliki tombol untuk menambahkan
produk baru. Tempatkan di App.
Di komponen induk, buat state
dengan array produk dan fungsi penambahan
produk baru. Teruskan mereka ke
komponen anak sebagai props, tampilkan di dalamnya
array yang diteruskan dalam bentuk daftar ul.
Di Products, tampilkan teks di konsol
'products render'.
Bungkus Products dengan memo.
Klik pada paragraf dan tombol. Pastikan,
bahwa saat mengklik paragraf, komponen anak
tetap di-render ulang.
Simpan fungsi untuk menambahkan
produk dalam cache, dengan membungkusnya dalam hook useCallback.
Klik pada paragraf dan tombol. Pastikan,
bahwa saat mengklik paragraf, komponen anak
tidak lagi di-render ulang.