Mempelajari Cara Menjinakkan React menggunakan Callback Hook

Diterbitkan: 2022-04-27

Bukan rahasia lagi bahwa React.js telah menjadi sangat populer dalam beberapa tahun terakhir. Sekarang perpustakaan JavaScript pilihan bagi banyak pemain internet yang paling menonjol, termasuk Facebook dan WhatsApp.

Salah satu alasan utama kemunculannya adalah pengenalan kait di versi 16.8. Kait React memungkinkan Anda memanfaatkan fungsionalitas React tanpa menulis komponen kelas. Sekarang komponen fungsional dengan kait telah menjadi struktur masuk pengembang untuk bekerja dengan React.

Dalam posting blog ini, kita akan menggali lebih dalam ke satu kait khusus — useCallback — karena menyentuh bagian mendasar dari pemrograman fungsional yang dikenal sebagai memoization. Anda akan tahu persis bagaimana dan kapan menggunakan hook useCallback dan memanfaatkan kemampuan peningkatan kinerjanya sebaik mungkin.

Siap? Mari selami!


Apa itu Memoisasi?

Memoisasi adalah ketika fungsi kompleks menyimpan outputnya sehingga lain kali dipanggil dengan input yang sama. Ini mirip dengan caching, tetapi pada tingkat yang lebih lokal. Itu dapat melewati perhitungan rumit apa pun dan mengembalikan output lebih cepat karena sudah dihitung.

Ini dapat memiliki efek signifikan pada alokasi memori dan kinerja, dan ketegangan itulah yang dimaksudkan untuk dikurangi oleh kait useCallback .

React useCallback vs useMemo

Pada titik ini, perlu disebutkan bahwa useCallback berpasangan dengan baik dengan kait lain yang disebut useMemo . Kita akan membahas keduanya, tetapi dalam bagian ini, kita akan fokus pada useCallback sebagai topik utama.

Perbedaan utamanya adalah useMemo mengembalikan nilai memo, sedangkan useCallback mengembalikan fungsi memo. Itu berarti useMemo digunakan untuk menyimpan nilai yang dihitung, sementara useCallback mengembalikan fungsi yang dapat Anda panggil nanti.

Kait ini akan mengembalikan versi yang di-cache kecuali salah satu dependensinya (misalnya status atau properti) berubah.

Mari kita lihat dua fungsi dalam aksi:

 import { useMemo, useCallback } from 'react' const values = [3, 9, 6, 4, 2, 1] // This will always return the same value, a sorted array. Once the values array changes then this will recompute. const memoizedValue = useMemo(() => values.sort(), [values]) // This will give me back a function that can be called later on. It will always return the same result unless the values array is modified. const memoizedFunction = useCallback(() => values.sort(), [values])

Cuplikan kode di atas adalah contoh yang dibuat-buat tetapi menunjukkan perbedaan antara dua panggilan balik:

  1. memoizedValue akan menjadi array [1, 2, 3, 4, 6, 9] . Selama variabel values ​​tetap ada, begitu juga memoizedValue , dan itu tidak akan pernah dihitung ulang.
  2. memoizedFunction akan menjadi fungsi yang akan mengembalikan array [1, 2, 3, 4, 6, 9] .

Apa yang hebat dari dua panggilan balik ini adalah mereka menjadi cache dan berkeliaran sampai array ketergantungan berubah. Ini berarti bahwa pada render, mereka tidak akan mengumpulkan sampah.

React.js sekarang menjadi perpustakaan JavaScript pilihan bagi banyak pemain internet terbesar, termasuk Facebook dan WhatsApp. Pelajari lebih lanjut dalam panduan ini ️ Klik untuk Tweet

Rendering dan Bereaksi

Mengapa memoisasi penting dalam React?

Ini ada hubungannya dengan bagaimana React merender komponen Anda. React menggunakan DOM Virtual yang disimpan dalam memori untuk membandingkan data dan memutuskan apa yang akan diperbarui.

DOM virtual membantu Bereaksi dengan kinerja dan menjaga aplikasi Anda tetap cepat. Secara default, jika ada nilai dalam komponen Anda berubah, seluruh komponen akan dirender ulang. Ini membuat React "reaktif" terhadap input pengguna dan memungkinkan layar untuk memperbarui tanpa memuat ulang halaman.

Anda tidak ingin merender komponen Anda karena perubahan tidak akan memengaruhi komponen itu. Di sinilah memoisasi melalui useCallback dan useMemo berguna.

Saat React merender ulang komponen Anda, React juga membuat ulang fungsi yang telah Anda deklarasikan di dalam komponen Anda.

Perhatikan bahwa ketika membandingkan kesetaraan suatu fungsi dengan fungsi lain, mereka akan selalu salah. Karena fungsi juga merupakan objek, itu hanya akan sama dengan dirinya sendiri:

 // these variables contain the exact same function but they are not equal const hello = () => console.log('Hello Matt') const hello2 = () => console.log('Hello Matt') hello === hello2 // false hello === hello // true

Dengan kata lain, ketika React merender ulang komponen Anda, ia akan melihat semua fungsi yang dideklarasikan dalam komponen Anda sebagai fungsi baru.

Ini baik-baik saja sebagian besar waktu, dan fungsi sederhana mudah dihitung dan tidak akan memengaruhi kinerja. Tetapi di lain waktu ketika Anda tidak ingin fungsi tersebut dilihat sebagai fungsi baru, Anda dapat mengandalkan useCallback untuk membantu Anda.

Anda mungkin berpikir, “Kapan saya tidak ingin suatu fungsi dilihat sebagai fungsi baru?” Nah, ada beberapa kasus ketika useCallback lebih masuk akal:

  1. Anda meneruskan fungsi ke komponen lain yang juga di memo ( useMemo )
  2. Fungsi Anda memiliki keadaan internal yang perlu diingat
  3. Fungsi Anda adalah ketergantungan dari kait lain, seperti useEffect misalnya

Manfaat Kinerja dari React useCallback

Ketika useCallback digunakan dengan tepat, ini dapat membantu mempercepat aplikasi Anda dan mencegah komponen dirender ulang jika tidak diperlukan.

Katakanlah, misalnya, Anda memiliki komponen yang mengambil data dalam jumlah besar dan bertanggung jawab untuk menampilkan data tersebut dalam bentuk bagan atau grafik, seperti ini:

Grafik batang warna-warni yang membandingkan keseluruhan waktu transaksi PHP, MySQL, Reddis, dan eksternal (lainnya) dalam milidetik.
Grafik batang dibuat menggunakan komponen React.

Misalkan komponen induk untuk komponen visualisasi data Anda dirender ulang, tetapi properti atau status yang diubah tidak memengaruhi komponen tersebut. Dalam hal ini, Anda mungkin tidak ingin atau perlu merender ulang dan mengambil kembali semua data. Menghindari perenderan ulang dan pengambilan ulang ini dapat menghemat bandwidth pengguna Anda dan memberikan pengalaman pengguna yang lebih lancar.

Berjuang dengan downtime dan masalah WordPress? Kinsta adalah solusi hosting yang dirancang untuk menghemat waktu Anda! Lihat fitur kami

Kekurangan React useCallback

Meskipun pengait ini dapat membantu Anda meningkatkan kinerja, pengait ini juga dilengkapi dengan jebakan. Beberapa hal yang perlu diperhatikan sebelum menggunakan useCallback (dan useMemo ) adalah:

  • Pengumpulan sampah: Fungsi lain yang belum di memo akan dibuang oleh React untuk mengosongkan memori.
  • Alokasi memori: Mirip dengan pengumpulan sampah, semakin banyak fungsi memo yang Anda miliki, semakin banyak memori yang dibutuhkan. Plus, setiap kali Anda menggunakan callback ini, ada banyak kode di dalam React yang perlu menggunakan lebih banyak memori untuk memberi Anda output yang di-cache.
  • Kompleksitas kode: Saat Anda mulai membungkus fungsi di kait ini, Anda segera meningkatkan kompleksitas kode Anda. Sekarang membutuhkan lebih banyak pemahaman tentang mengapa kait ini digunakan dan konfirmasi bahwa mereka digunakan dengan benar.

Menyadari perangkap di atas dapat menyelamatkan Anda dari sakit kepala karena tersandung sendiri. Saat mempertimbangkan untuk menggunakan useCallback , pastikan manfaat kinerjanya lebih besar daripada kerugiannya.

React useCallback Contoh

Di bawah ini adalah pengaturan sederhana dengan komponen Button dan komponen Counter. Penghitung memiliki dua bagian status dan menampilkan dua komponen Tombol, masing-masing akan memperbarui bagian terpisah dari status komponen Penghitung.

Komponen Button memiliki dua props: handleClick dan name. Setiap kali Tombol dirender, itu akan masuk ke konsol.

 import { useCallback, useState } from 'react' const Button = ({handleClick, name}) => { console.log(`${name} rendered`) return <button onClick={handleClick}>{name}</button> } const Counter = () => { console.log('counter rendered') const [countOne, setCountOne] = useState(0) const [countTwo, setCountTwo] = useState(0) return ( <> {countOne} {countTwo} <Button handleClick={() => setCountOne(countOne + 1)} name="button1" /> <Button handleClick={() => setCountTwo(countTwo + 1)} name="button1" /> </> ) }

Dalam contoh ini, setiap kali Anda mengklik salah satu tombol, Anda akan melihat ini di konsol:

 // counter rendered // button1 rendered // button2 rendered

Sekarang, jika kita menerapkan useCallback ke fungsi handleClick kita dan membungkus Button kita di React.memo , kita dapat melihat apa yang useCallback kepada kita. React.memo mirip dengan useMemo dan memungkinkan kita untuk memoize sebuah komponen.

 import { useCallback, useState } from 'react' const Button = React.memo(({handleClick, name}) => { console.log(`${name} rendered`) return <button onClick={handleClick}>{name}</button> }) const Counter = () => { console.log('counter rendered') const [countOne, setCountOne] = useState(0) const [countTwo, setCountTwo] = useState(0) const memoizedSetCountOne = useCallback(() => setCountOne(countOne + 1), [countOne) const memoizedSetCountTwo = useCallback(() => setCountTwo(countTwo + 1), [countTwo]) return ( <> {countOne} {countTwo} <Button handleClick={memoizedSetCountOne} name="button1" /> <Button handleClick={memoizedSetCountTwo} name="button1" /> </> ) }

Sekarang ketika kita mengklik salah satu tombol, kita hanya akan melihat tombol yang kita klik untuk masuk ke konsol:

 // counter rendered // button1 rendered // counter rendered // button2 rendered

Kami telah menerapkan memoisasi ke komponen tombol kami, dan nilai prop yang diteruskan ke sana terlihat sama. Kedua fungsi handleClick di-cache dan akan dilihat sebagai fungsi yang sama oleh React hingga nilai item dalam larik dependensi berubah (misalnya countOne , countTwo ).

Siap untuk mempelajari dengan tepat bagaimana dan kapan menggunakan hook useCallback, serta bagaimana memanfaatkan kemampuan terbaiknya untuk meningkatkan kinerja? Mulailah di sini! Klik untuk Tweet

Ringkasan

useCallback dan useMemo , ingatlah bahwa mereka memiliki kasus penggunaan khusus — Anda tidak boleh membungkus setiap fungsi dengan kait ini. Jika fungsinya kompleks secara komputasi, ketergantungan dari hook atau prop lain yang diteruskan ke komponen memo adalah indikator bagus yang mungkin ingin Anda jangkau useCallback .

Kami harap artikel ini membantu Anda memahami fungsionalitas React tingkat lanjut ini dan membantu Anda mendapatkan lebih banyak kepercayaan diri dengan pemrograman fungsional di sepanjang jalan!