Hook Pengoptimuman Prestasi useMemo dalam React
Hook pertama untuk pengoptimuman
prestasi yang akan kami pertimbangkan
ialah useMemo.
Hook ini membantu mengcache hasil operasi yang memakan sumber antara saat lukisan semula skrin dan seterusnya boleh membantu mengelakkan pengiraan yang berlebihan dan besar. Cache sedemikian juga dipanggil pememoan.
Mari kita lihat bagaimana ia berfungsi. Mari
buat komponen dengan butang dan
tajuk h3:
return (
<div>
<h3>Text</h3>
<button>click</button>
</div>
);
Dan sekarang mari kita buat supaya apabila diklik
pada tajuk, warnanya berubah daripada oren
kepada hijau dan sebaliknya. Sebagai permulaan,
mari buat state isGreen:
const [isGreen, setIsGreen] = useState(false);
Mari tambah syarat perubahan warna pada tajuk
dalam atribut style dan
tambahkan pengendali klik:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Text</h3>
Katakan kita juga mempunyai beberapa nilai, yang akan meningkat sebanyak satu apabila diklik pada butang kami. Mari buat state untuknya:
const [num, setNum] = useState(0);
Mari tambah pengendalian klik pada butang:
<button onClick={() => setNum(num + 1)}>
klik
</button>
Katakan kita juga mempunyai fungsi tertentu
square, yang akan memulangkan
kuasa dua nilai num. Hasil
pemanggilan fungsi kami akan tulis ke dalam
pembolehubah result:
const result = square(num);
function square(num) {
return num * num;
}
Mari paparkan result dalam teks butang:
<button onClick={() => setNum(num + 1)}>
klik: {result}
</button>
Hasilnya, kami mendapat yang berikut:
apabila butang diklik, nilai
num berubah, yang kemudiannya dikuasa duakan,
dan apabila tajuk diklik
warna tajuk berubah.
Kami mempunyai komponen yang sangat kecil, semuanya berfungsi dengan pantas, walaupun apabila diklik pada tajuk untuk menukar warnanya, keseluruhan komponen dilukis semula, oleh itu pengiraan yang berkaitan dengan butang juga berlaku semula, walaupun kami tidak menyentuhnya. Dan sekarang bayangkan jika pengiraan kami adalah besar dan semuanya dikira semula setiap kali.
Mari kita beratkan fungsi kami sedikit, sekarang ia akan "berfikir" sedikit lebih lama. Dengan cara ini kami akan mensimulasikan pengiraan yang lama:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Hanya buat tidak apa-apa ...
}
return num * num;
}
Sekarang cuba klik pada tajuk. Ternyata
sekarang disebabkan oleh fungsi square
yang mengambil masa lama (dan kami tidak menyentuh butang!)
kami terpaksa menunggu selama-lamanya untuk
tajuk menukar warnanya!
Di sinilah hook useMemo
datang untuk menyelamatkan. Untuk ini, kami perlu
menghantar fungsi sebagai parameter pertama, yang mengira
nilai yang ingin kami cache,
fungsi ini mestilah tulen dan tidak
menerima sebarang parameter. Dan parameter kedua
ialah kebergantungan dalam kurungan segi empat,
dengan kata lain, semua nilai reaktif
yang terlibat dalam kod
fungsi. Oleh itu, dalam result
kini kami akan tulis pembinaan seperti ini:
const result = useMemo(() => square(num), [num]);
Mari klik pada tajuk sekali lagi. Sekarang,
jika kami tidak menyentuh butang dengan pengiraan
dan tidak menukar nilai state
num, maka tiada apa yang dikira semula,
dan React memaparkan nilai yang dicache
dalam butang, oleh itu tajuk kami
dengan pantas menukar warnanya.
Buat komponen App, letakkan
perenggan di dalamnya. Buat state text
dengan nilai awal 'react',
biarkan nilai state dipaparkan
sebagai teks perenggan. Biarkan apabila diklik
pada perenggan, tanda seru ditambah
pada hujung teks.
Buat satu lagi state num, dengan
nilai awal 0. Letakkan dalam
App satu lagi perenggan. Buat supaya
apabila diklik padanya, num
bertambah sebanyak 1.
Dan sekarang tambahkan dalam App fungsi
triple, yang menerima
num sebagai parameter dan
memulangkan nilai tiga kali ganda daripadanya.
Letakkan hasil panggilan fungsi
ke dalam pembolehubah result. Paparkan
result sebagai teks perenggan kedua. Klik
secara bergilir-gilir pada perenggan,
perhatikan betapa perlunya tanda seru ditambah.
Betulkan keadaan, dengan membungkus fungsi
yang perlahan triple dalam useMemo.