Praktik Terbaik Dengan React Hooks
Diterbitkan: 2022-03-10 React Hooks adalah tambahan baru di React 16.8 yang memungkinkan Anda menggunakan status dan fitur React lainnya tanpa menulis komponen class
. Dengan kata lain, Hooks adalah fungsi yang memungkinkan Anda "menghubungkan" status React dan fitur siklus hidup dari komponen fungsi. (Mereka tidak bekerja di dalam komponen class
.)
React menyediakan beberapa Kait bawaan seperti useState
. Anda juga dapat membuat Hooks Anda sendiri untuk menggunakan kembali perilaku stateful di antara komponen yang berbeda. Contoh di bawah ini menunjukkan penghitung yang statusnya dikelola menggunakan kait useState()
. Setiap kali Anda mengklik tombol, kami menggunakan setCount()
untuk memperbarui nilai count
sebesar 1
.
Contoh ini membuat penghitung dengan nilai 0
. Saat Anda mengklik tombol, itu menambah nilai sebesar 1
. Nilai awal komponen ditentukan menggunakan useState
.
const [count, setCount] = useState(0)
Seperti yang Anda lihat, kami menetapkannya menjadi 0
. Kemudian kita menggunakan metode onClick()
untuk memanggil setCount
saat kita ingin menaikkan nilainya.
<button onClick={() => setCount(count + 1)}> Click me </button>
Sebelum rilis React Hooks, contoh ini akan menggunakan lebih banyak baris kode, karena kita harus menggunakan komponen class
.
Aturan Kait Bereaksi
Sebelum kita menyelam jauh ke dalam praktik terbaik, kita perlu memahami aturan React Hooks yang juga merupakan beberapa konsep dasar praktik yang disajikan dalam artikel ini.
React Hooks adalah fungsi JavaScript, tetapi Anda harus mengikuti dua aturan saat menggunakannya.
- Panggil Hooks di tingkat atas;
- Hanya panggil Hooks dari komponen React.
Catatan : Kedua aturan ini diperkenalkan di React Hooks, bukan menjadi bagian dari JavaScript itu sendiri.
Mari kita lihat aturan ini secara lebih rinci.
Hubungi Kait Di Tingkat Atas
Jangan panggil Hooks di dalam loop, kondisi, atau fungsi bersarang. Selalu gunakan Hooks di level teratas dari fungsi React Anda. Dengan mengikuti aturan ini, Anda memastikan bahwa Hooks dipanggil dalam urutan yang sama setiap kali komponen dirender. Itulah yang memungkinkan React untuk mempertahankan status Hooks dengan benar antara beberapa panggilan useState
dan useEffect
.
Mari kita buat komponen Form
yang akan memiliki dua status:
-
accountName
-
accountDetail
Status ini akan memiliki nilai default, kami akan menggunakan kait useEffect
untuk mempertahankan status ke penyimpanan lokal browser kami atau ke judul dokumen kami.
Sekarang, komponen ini mungkin akan berhasil mengelola statusnya jika tetap sama antara beberapa panggilan useState
dan useEffect
.
function Form() { // 1. Use the accountName state variable const [accountName, setAccountName] = useState('David'); // 2. Use an effect for persisting the form useEffect(function persistForm() { localStorage.setItem('formData', accountName); }); // 3. Use the accountDetail state variable const [accountDetail, setAccountDetail] = useState('Active'); // 4. Use an effect for updating the title useEffect(function updateStatus() { document.title = accountName + ' ' + accountDetail; }); // ... }
Jika urutan Hooks kami berubah (yang dapat dimungkinkan ketika dipanggil dalam loop atau kondisional), React akan kesulitan mencari cara untuk mempertahankan status komponen kami.
// ------------ useState('David') // 1. Initialize the accountName state variable with 'David' useEffect(persistForm) // 2. Add an effect for persisting the form useState('Active') // 3. Initialize the accountdetail state variable with 'Active' useEffect(updateStatus) // 4. Add an effect for updating the status // ------------- // Second render // ------------- useState('David') // 1. Read the accountName state variable (argument is ignored) useEffect(persistForm) // 2. Replace the effect for persisting the form useState('Active') // 3. Read the accountDetail state variable (argument is ignored) useEffect(updateStatus) // 4. Replace the effect for updating the status // ...
Itulah urutan yang diikuti React untuk memanggil hook kita. Karena urutannya tetap sama, itu akan dapat mempertahankan status komponen kami. Tapi apa yang terjadi jika kita menempatkan panggilan Hook di dalam suatu kondisi?
// We're breaking the first rule by using a Hook in a condition if (accountName !== '') { useEffect(function persistForm() { localStorage.setItem('formData', accountName); }); }
Kondisi accountName !== ''
true
pada render pertama, jadi kami menjalankan Hook ini. Namun, pada render berikutnya, pengguna mungkin menghapus formulir, membuat kondisi menjadi false
. Sekarang setelah kita melewati Hook ini selama rendering, urutan panggilan Hook menjadi berbeda:
useState('David') // 1. Read the accountName state variable (argument is ignored) // useEffect(persistForm) // This Hook was skipped! useState('Active') // 2 (but was 3). Fail to read the accountDetails state variable useEffect(updateStatus) // 3 (but was 4). Fail to replace the effect
React tidak akan tahu apa yang harus dikembalikan untuk panggilan useState
Hook kedua. React mengharapkan bahwa panggilan Hook kedua dalam komponen ini sesuai dengan efek persistForm
, seperti pada render sebelumnya — tetapi sekarang tidak lagi. Sejak saat itu, setiap panggilan Hook
berikutnya setelah yang kami lewati juga akan bergeser satu per satu — yang mengarah ke bug.
Inilah sebabnya mengapa Hooks harus dipanggil di tingkat atas komponen kami. Jika kita ingin menjalankan efek secara kondisional, kita dapat menempatkan kondisi itu di dalam Hook kita.
Catatan : Lihat dokumen React Hook untuk membaca lebih lanjut tentang topik ini.
Hanya Panggil Hooks Dari React Components
Jangan panggil Hooks dari fungsi JavaScript biasa. Sebagai gantinya, Anda dapat memanggil Hooks dari komponen fungsi React. Mari kita lihat perbedaan antara fungsi JavaScript dan komponen React di bawah ini:
Fungsi JavaScript
import { useState } = "react"; function toCelsius(fahrenheit) { const [name, setName] = useState("David"); return (5/9) * (fahrenheit-32); } document.getElementById("demo").innerHTML = toCelsius;
Di sini kita mengimpor kait useState
dari paket React, dan kemudian mendeklarasikan fungsi kita. Tapi ini tidak valid karena ini bukan komponen React.
Fungsi Bereaksi
import React, { useState} from "react"; import ReactDOM from "react-dom"; function Account(props) { const [name, setName] = useState("David"); return <p>Hello, {name}! The price is <b>{props.total}</b> and the total amount is <b>{props.amount}</b></p> } ReactDom.render( <Account total={20} amount={5000} />, document.getElementById('root') );
Meskipun tubuh keduanya terlihat mirip, yang terakhir menjadi komponen saat kita mengimpor React ke dalam file. Inilah yang memungkinkan kita untuk menggunakan hal-hal seperti JSX dan React hook di dalamnya.
Jika Anda kebetulan mengimpor hook pilihan Anda tanpa mengimpor React (yang menjadikannya fungsi biasa), Anda tidak akan dapat menggunakan Hook yang telah Anda impor karena Hook hanya dapat diakses di komponen React.
Panggil Kait Dari Kait Kustom
Hook kustom adalah fungsi JavaScript yang namanya dimulai dengan use
dan dapat memanggil Hooks lainnya. Misalnya, useUserName
digunakan di bawah Hook khusus yang memanggil kait useState
dan useEffect
. Ini mengambil data dari API, mengulang data, dan memanggil setIsPresent()
jika nama pengguna tertentu yang diterima ada dalam data API.
export default function useUserName(userName) { const [isPresent, setIsPresent] = useState(false); useEffect(() => { const data = MockedApi.fetchData(); data.then((res) => { res.forEach((e) => { if (e.name === userName) { setIsPresent(true); } }); }); }); return isPresent; }
Kami kemudian dapat melanjutkan untuk menggunakan kembali fungsionalitas kait ini di tempat lain di mana kami membutuhkannya di aplikasi kami. Di tempat seperti itu, kecuali saat dibutuhkan, kita tidak perlu memanggil useState
atau useEffect
lagi.
Dengan mengikuti aturan ini, Anda memastikan bahwa semua logika stateful dalam komponen terlihat jelas dari kode sumbernya.
Plugin ESLint
Plugin ESLint yang disebut eslint-plugin-react-hooks
memberlakukan aturan di atas. Ini berguna dalam menegakkan aturan saat mengerjakan sebuah proyek. Saya sarankan Anda menggunakan plugin ini saat mengerjakan proyek Anda, terutama saat bekerja dengan orang lain. Anda dapat menambahkan plugin ini ke proyek Anda jika Anda ingin mencobanya:
// Your ESLint configuration { "plugins": [ // ... "react-hooks" ], "rules": { // ... "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies } }
Plugin ini disertakan secara default di Create React App. Jadi Anda tidak perlu menambahkannya jika Anda mem-bootstrap aplikasi React Anda menggunakan Create-React-App.
Berpikir Dalam Kait
Mari kita lihat sekilas komponen class
dan komponen fungsional (dengan Hooks), sebelum menyelami beberapa praktik terbaik Hooks.
Cara paling sederhana untuk mendefinisikan komponen di React adalah dengan menulis fungsi JavaScript yang mengembalikan elemen React:
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
Komponen Welcome
menerima props
yang merupakan objek yang berisi data dan mengembalikan elemen React. Kami kemudian dapat mengimpor dan merender komponen ini di komponen lain.
Komponen class
menggunakan metodologi pemrograman yang disebut Enkapsulasi yang pada dasarnya berarti bahwa segala sesuatu yang relevan dengan komponen kelas akan hidup di dalamnya. Metode siklus hidup ( constructors
, componentDidMount()
, render
, dan seterusnya) memberikan komponen struktur yang dapat diprediksi.
Enkapsulasi adalah salah satu dasar dari OOP ( O bject- O oriented P rogramming). Ini mengacu pada bundling data dalam metode yang beroperasi pada data itu, dan digunakan untuk menyembunyikan nilai atau status objek data terstruktur di dalam kelas — mencegah akses langsung pihak yang tidak berwenang ke sana.
Dengan Hooks, komposisi komponen berubah dari kombinasi siklus hidup Hooks — menjadi fungsionalitas dengan beberapa render di akhir.
Komponen Fungsi
Contoh di bawah ini menunjukkan bagaimana Hook khusus dapat digunakan dalam komponen fungsional (tanpa menunjukkan apa isi tubuhnya). Namun, apa yang dilakukannya atau dapat dilakukan tidak terbatas. Itu bisa berupa membuat variabel status, menggunakan konteks, berlangganan komponen ke berbagai efek samping — atau semua hal di atas jika Anda menggunakan kait khusus!
function { useHook{...}; useHook{...}; useHook{...}; return (
...); }
Komponen Kelas
Sebuah komponen class
mengharuskan Anda untuk memperluas dari React.Component
dan membuat fungsi render
yang mengembalikan elemen React. Ini membutuhkan lebih banyak kode tetapi juga akan memberi Anda beberapa manfaat.
class { constructor(props) {...} componentDidMount() {...} componentWillUnmount() {...} render() {...} }
Ada beberapa manfaat yang Anda dapatkan dengan menggunakan komponen fungsional di React:
- Akan lebih mudah untuk memisahkan wadah dan komponen presentasi karena Anda perlu lebih memikirkan status komponen Anda jika Anda tidak memiliki akses ke
setState()
di komponen Anda. - Komponen fungsional jauh lebih mudah untuk dibaca dan diuji karena merupakan fungsi JavaScript biasa tanpa kait status atau siklus hidup.
- Anda berakhir dengan lebih sedikit kode.
- Tim React menyebutkan bahwa mungkin ada peningkatan kinerja untuk komponen fungsional di versi React mendatang.
Ini mengarah pada praktik terbaik pertama saat menggunakan React Hooks.
Kait Praktik Terbaik
1. Sederhanakan Kait Anda
Menjaga React Hooks tetap sederhana akan memberi Anda kekuatan untuk mengontrol dan memanipulasi secara efektif apa yang terjadi dalam komponen sepanjang masa pakainya. Hindari menulis Kait kustom sebanyak mungkin ; Anda dapat memasukkan useState()
atau useEffect()
alih-alih membuat hook Anda sendiri.
Jika Anda menemukan diri Anda menggunakan sekelompok Hook khusus yang terkait dalam fungsionalitas, Anda dapat membuat kait khusus yang bertindak sebagai pembungkus untuk ini. Mari kita lihat dua komponen fungsional yang berbeda dengan pengait di bawah ini.
Komponen Fungsional v1
function { useHook(...); useHook(...); useHook(...); return( <div>...</div> ); }
Komponen Fungsional v2
function { useCustomHook(...); useHook(...); useHook(...); return( <div>...</div> ); }
v2 adalah versi yang lebih baik karena membuat hook tetap sederhana dan semua useHook
lainnya sejalan. Ini memungkinkan kami membuat fungsionalitas yang dapat digunakan kembali di berbagai komponen dan juga memberi kami lebih banyak kekuatan untuk mengontrol dan memanipulasi komponen kami secara efektif. Alih-alih mengadopsi v1 di mana komponen kita dipenuhi dengan Hooks, Anda harus menggunakan v2 yang akan membuat debugging menjadi mudah dan kode Anda lebih bersih.
2. Atur dan Susun Kait Anda
Salah satu keunggulan React Hooks adalah kemampuannya untuk menulis lebih sedikit kode yang mudah dibaca. Dalam beberapa kasus, jumlah useEffect()
dan useState()
masih bisa membingungkan. Saat Anda menjaga komponen tetap teratur, ini akan membantu keterbacaan dan menjaga aliran komponen Anda tetap konsisten dan dapat diprediksi. Jika Hook kustom Anda terlalu rumit, Anda selalu dapat memecahnya menjadi Hooks sub-kustom. Ekstrak logika komponen Anda ke Hooks khusus agar kode Anda dapat dibaca.
3. Gunakan Cuplikan React Hooks
React Hooks Snippets adalah ekstensi Kode Visual Studio untuk membuat React Hooks lebih mudah dan lebih cepat. Saat ini, lima kait didukung:
-
useState()
-
useEffect()
-
useContext()
-
useCallback()
-
useMemo()
Cuplikan lain juga telah ditambahkan. Saya telah mencoba bekerja dengan Hooks ini dan ini telah menjadi salah satu praktik terbaik yang saya gunakan secara pribadi saat bekerja dengan mereka.
Ada dua cara Anda dapat menambahkan cuplikan React Hooks ke proyek Anda:
- Memerintah
Luncurkan VS Code Quick open ( Ctrl + P ), rekatkanext install ALDuncanson.react-hooks-snippets
dan tekan Enter . - Pasar Ekstensi
Luncurkan 'VS Code Extension Marketplace' ( Ctrl + Shift + X ) dan cari 'React Hook Snippets'. Kemudian, cari ikon 'Alduncanson'.
Saya merekomendasikan cuplikan pertama. Baca lebih lanjut tentang cuplikan di sini atau periksa cuplikan Hooks terbaru di sini.
4. Masukkan Aturan Kait Sebagai Pertimbangan
Berusahalah untuk selalu mempertimbangkan dua aturan Hooks yang telah kita pelajari sebelumnya saat bekerja dengan React Hooks.
- Hanya panggil Hooks Anda di tingkat atas. Jangan panggil Hooks di dalam loop, kondisi, atau fungsi bersarang.
- Selalu panggil Hooks dari komponen fungsi React atau dari Custom Hooks, jangan panggil Hooks dari fungsi JavaScript biasa.
Plugin ESlint yang disebut eslint-plugin-react-hooks
memberlakukan dua aturan ini, Anda dapat menambahkan plugin ini ke proyek Anda jika Anda menginginkannya seperti yang kami jelaskan di atas di bagian aturan kait.
Praktik terbaik belum sepenuhnya diselesaikan karena Hooks masih relatif baru. Jadi adopsi harus diambil dengan kehati-hatian yang akan diambil seseorang dalam mengadopsi teknologi awal apa pun. Dengan pemikiran itu, Hooks adalah jalan untuk masa depan React.
Kesimpulan
Saya harap Anda menikmati tutorial ini. Kita telah mempelajari dua aturan terpenting dari React Hooks dan cara berpikir efektif di Hooks. Kami melihat komponen fungsional dan beberapa praktik terbaik dalam menulis Hooks dengan cara yang benar dan efektif. Meskipun aturannya singkat, penting untuk menjadikannya sebagai pedoman Anda saat menulis aturan. Jika Anda cenderung melupakannya, Anda dapat menggunakan plugin ESLint untuk menerapkannya.
Saya harap Anda akan mengambil semua pelajaran yang didapat di sini dalam proyek React Anda berikutnya. Semoga beruntung!
Sumber daya
- “Memperkenalkan Hooks,” React Docs
- “Fungsional vs Komponen Kelas Dalam Bereaksi,” David Joch, Medium
- “Mixin Dianggap Berbahaya,” Dan Abramov, React Blog
- “React Hooks: Praktik Terbaik Dan Perubahan Pola Pikir,” Bryan Manuele, Medium
- “React Hooks Snippets Untuk VS Code,” Anthony Davis, Visual Code Marketplace