Demystifying React Hooks — useCallback

Dec 03 2022
Pada artikel ini, kita akan mengeksplorasi kapan dan bagaimana menggunakan hook useCallback React dan kesalahan yang dibuat oleh sebagian besar Pengembang Junior.
Memulai Jika Anda ingin mengikuti IDE lokal Anda, Anda dapat menemukan Repo GitHub di sini. Kesetaraan Referensial adalah konsep dasar dalam JavaScript dan Ilmu Komputer secara keseluruhan.

Mulai

Jika Anda ingin mengikuti IDE lokal Anda, Anda dapat menemukan Repo GitHub di sini .

  • clone
  • cd client
  • npm i
  • npm start

Kesetaraan Referensial adalah konsep dasar dalam JavaScript dan Ilmu Komputer secara keseluruhan. Jadi mari kita mulai dengan mendemonstrasikannya dalam aksi.

Saya telah menyematkan tangkapan layar di seluruh artikel untuk kemudahan penggunaan di perangkat seluler. Jika Anda menggunakan desktop dan telah mengkloningnya, jalankan referentialEquality.jsuntuk mengamati output atau cukup mainkan dengan cuplikan JSFiddle yang disematkan di bawah.

Saat mengevaluasi apakah integer 1sama persis dengan integer 1, konsol mencetak true. Ini karena, yah… ini integer 1 benar -benar sama dengan integer 1.

bilangan bulat benar-benar sama

Kami melihat hasil yang sama saat mengevaluasi dua string.

string benar-benar sama

Jelas, ini akan selalu berlaku untuk dua tipe data primitif dengan nilai yang sama.

Sekarang, bagaimana dengan struktur data? Misalnya, dua literal objek dengan pasangan kunci/nilai yang sama? Bagaimana dengan literal objek kosong?

objek tidak sepenuhnya sama

Mengapa ini dicetak false? Saat membandingkan apakah kedua literal objek ini benar-benar sama, JavaScript menggunakan alamat memori masing-masing .

Dengan kata lain, kedua objek ini mungkin berisi nilai yang sama , tetapi keduanya tidak mereferensikan objek yang sama . Mereka terlihat sama tetapi menempati dua ruang berbeda dalam memori .

Hal yang sama berlaku apakah Anda membandingkan dua literal objek, dua literal array, atau dua fungsi!

array tidak sepenuhnya sama

Untuk mendemonstrasikan ini lebih jauh, kita akan mendefinisikan sebuah function func, yang mengembalikan sebuah fungsi anonim yang, pada gilirannya, mengembalikan sesuatu yang lain ( seperti elemen JSX ).

membuat komponen fungsional pura-pura

Kami kemudian akan menetapkan dua fungsi yang berbeda, firstRenderdan secondRender, sama dengan nilai yang dikembalikan oleh func.

menugaskan definisi fungsi kami

Anggap funcsebagai komponen fungsional React Anda, while firstRenderadalah fungsi di dalamnya pada render pertama, dan secondRendermerupakan fungsi di dalamnya pada render kedua.

Meskipun firstRenderdan secondRendermengembalikan nilai yang sama dan ditugaskan dari definisi yang sama, mereka tidak memiliki persamaan referensial . Hasilnya, setiap kali komponen dirender, fungsi ini didefinisikan ulang.

dua fungsi kita tidak sepenuhnya sama

Sayangnya, dalam JavaScript, tidak mudah untuk mencetak alamat memori ini seperti di Python, tetapi untuk penjelasan yang lebih mendalam tentang referensi vs. nilai, lihat artikel ini dari freeCodeCamp.

Topik ini bisa menjadi padat, dan Anda tidak perlu mengajar di kelas malam ini. Jadi, untuk saat ini, ingat saja:

  • tipe data primitif tipe ===data primitif
  • struktur data !==struktur data.

Kode Pemula

Setelah kami menjalankan aplikasi kami, buka BookDetails.jsxkomponen dan simpan kembali. Hal pertama yang mungkin kami perhatikan di server React dev kami adalah hal umum WARNINGyang cenderung diabaikan oleh pengembang muda. Saat Anda masuk ke dunia kerja dan mulai menulis kode untuk produksi, linter Anda akan menjadi lebih ketat daripada yang ada di dalamnya create-react-app. WARNINGSakan beralih ke ERRORS, dan beberapa linter tidak mengizinkan Anda untuk mendorong sebelum Anda mengatasinya ERRORS.

Jadi daripada mengabaikannya, mari cari tahu cara mengobatinya.

Solusi yang diusulkan React

CATATAN: Anda mungkin perlu menyimpan ulang terlebih dahulu BookDetails.jsxuntuk membuat iniWARNING

Jika kita menggali ke dalam React Docs , kita dapat mendekode solusi yang diusulkan semi-membingungkan untuk ini WARNINGsebagai berikut:

1. Sertakan definisi fungsi di dalam useEffect.

  • Kami tidak dapat memanggil fungsi ini di tempat lain kecuali kami mendefinisikannya kembali.
  • Ini akan memicu useEffect setiap kali status atau properti berubah, terkadang menyebabkan render ulang tanpa batas. Dan dalam kasus kita, karena kita memanggil fungsi setter status kita setelah panggilan API, itu bisa membebani API kita dengan permintaan titik akhir yang tak terbatas.
  • Fungsi tidak akan dipanggil.
  • Pertama kali komponen merender, ia akan menentukan fungsi kita, yang akan memicu useEffect, yang akan menyebabkan komponen merender ulang, yang akan mendefinisikan ulang fungsi, yang akan memicu useEffect, yang akan menyebabkan komponen merender ulang, yang akan mendefinisikan ulang fungsi…

Solusi paling sederhana dan disukai adalah dengan 'memasukkannya', yaitu, memindahkan getBookDetailsdefinisi fungsi ke dalam useEffect. Ini menganut prinsip Pemrograman Berorientasi Objek yang dikenal sebagai Enkapsulasi .

Tapi katakanlah kita tahu kita perlu memanggil fungsi di tempat lain. Haruskah kita mendefinisikan ulang nanti? Itu tidak terlalu KERING dari kita.

Mari kita ubah susunan dependensi kita untuk memasukkan referensi fungsi kita. Anda useEffectsekarang harus terlihat seperti ini.

termasuk fungsi kami dalam array ketergantungan

Dan getBookDetailstetap didefinisikan di atas useEffect.

definisi asli fungsi kita

Sekarang kita punya yang baruWARNING

mendefinisikan fungsi kita di luar useEffect sambil memasukkannya ke dalam array dependensi akan menyebabkan render ulang tanpa batas

Masukkan Kait useCallback

Singkatnya, useCallbackhook memungkinkan Anda untuk meng-cache, atau 'memoize', sebuah fungsi antara render ulang komponen Anda. Itu melakukan tugas yang mirip dengan useMemo, nuansa yang akan kita bahas di artikel lain.

Jika seluk-beluk ini menarik minat Anda, Anda dapat membaca lebih lanjut di React docs .

Harap perhatikan peringatan mereka:

Anda hanya harus mengandalkan useCallbacksebagai pengoptimalan kinerja. Jika kode Anda tidak berfungsi tanpanya, temukan masalah mendasar dan perbaiki terlebih dahulu. Kemudian Anda dapat menambahkan useCallbackuntuk meningkatkan kinerja.

useCallbackSintaksis

useCallbackSintaksnya sangat mirip dengan useEffectsintaksis yang sudah kita ketahui. Lihatlah kerangka masing-masing.

kedua kait memiliki kerangka sintaksis yang identik

Perbedaan kecilnya adalah dengan useEffect, kami memberi tahu fungsi anonim untuk menjalankan fungsi kami sementara dengan useCallback, kami menetapkan nilai pengembalian ke referensi untuk dipanggil di tempat lain.

Menggunakan useCallback

Pertama, kita akan mengimpor useCallbackdari 'react'. Daripada menambahkan baris baru, yang terbaik adalah merusaknya bersama dengan impor kami yang lain.

item yang didestrukturisasi dari paket yang sama paling baik diimpor pada baris yang sama

Sekarang kita dapat menetapkan getBookDetailsnilai yang dikembalikan dari useCallbackpemanggilan fungsi.

tetapkan pengembalian useCallback ke referensi kami

Kemudian kami menambahkan semua sintaks untuk useCallback. Ingat susunan ketergantungan Anda!

isi kerangka useCallback

Dalam contoh kita, kita perlu asyncsebelum parameter kita.

tambahkan asinkron

Dan terakhir, kami menambahkan logika fungsi kami ke dalam blok kode.

tambahkan logika kita ke blok kode useCallback

Setelah kami simpan, kami mendapatkan… yang lain WARNING.

pengembalian useCallback tergantung pada nilai id

Mengapa larik ketergantungan kita harus melacak idvariabel?

Mari kita pikirkan ini.

  • Jika nilai idperubahan, getBookDetailsperlu mencapai titik akhir yang berbeda, maka React harus mendefinisikannya kembali. Definisi getBookDetailssecara harfiah tergantung pada nilai id.
versi selesai dari kedua kait

Dan akhirnya, itu saja! Kami melihat warna hijau di server React dev kami. Linter yang bahagia adalah Pengembang Senior yang bahagia. Dan Pengembang Senior yang bahagia adalah Anda yang bahagia!

Saya selalu mencari teman dan kolega baru. Jika menurut Anda artikel ini bermanfaat dan ingin terhubung, Anda dapat menemukan saya di salah satu rumah saya di web.

GitHub | Twitter | LinkedIn | Situs web

Sumber daya

  • Kesetaraan Referensi
  • Tipe Data Primitif JavaScript vs. Struktur Data
  • Enkapsulasi
  • useCallback
  • Bereaksi Dokumen