Custom Hooks adalah salah satu fitur paling powerful yang diperkenalkan di React dengan hadirnya Hooks. Mereka memungkinkan Anda mengekstrak logic stateful yang dapat digunakan kembali dari komponen dan membagikannya ke berbagai komponen lain, tanpa perlu menulis ulang kode atau menggunakan render props dan higher-order components. Ini adalah cara yang bersih dan efisien untuk mengelola logic kompleks dan menjaga komponen Anda tetap fokus pada rendering UI.
Apa Itu Custom Hooks?
Singkatnya, Custom Hooks adalah fungsi JavaScript biasa yang namanya diawali dengan use
dan dapat memanggil Hooks React lainnya.
Filosofi di baliknya adalah "separation of concerns":
-
Komponen React seharusnya fokus pada rendering UI.
-
Custom Hooks seharusnya fokus pada logic stateful (misalnya, fetching data, mengelola form input, event listeners).
Ketika Anda mengekstrak logic ini ke dalam custom hook, Anda dapat menggunakannya di mana pun Anda mau, layaknya hook bawaan React (useState
, useEffect
, useContext
, dll.).
Mengapa Menggunakan Custom Hooks?
-
Reusability (Dapat Digunakan Kembali): Ini adalah alasan utama. Anda menulis logic sekali dan menggunakannya di banyak komponen.
-
Readability (Keterbacaan): Komponen Anda menjadi lebih bersih, lebih pendek, dan lebih mudah dibaca karena logic kompleks telah dipisahkan.
-
Maintainability (Kemudahan Perawatan): Ketika ada bug dalam logic, Anda hanya perlu memperbaikinya di satu tempat (di dalam custom hook).
-
Testability (Kemudahan Pengujian): Logic yang terpisah lebih mudah diuji secara independen.
-
Mengatasi Prop Drilling & Complex HOCs: Memberikan alternatif yang lebih elegan daripada prop drilling atau membangun higher-order components yang berlapis-lapis untuk berbagi logic.
Aturan Custom Hooks
Ada dua aturan dasar yang perlu diingat saat membuat dan menggunakan Hooks (termasuk Custom Hooks):
-
Hanya Panggil Hooks dari Fungsi React: Jangan memanggil Hooks dari loop, kondisi, atau fungsi bersarang biasa. Panggil mereka hanya di level atas fungsi komponen React atau dari Custom Hooks lainnya.
-
Hanya Panggil Hooks dari Fungsi Komponen React atau Custom Hooks Biasa: Jangan panggil Hooks dari fungsi JavaScript biasa. Mereka harus berada di dalam komponen fungsional React atau Custom Hooks Anda sendiri.
Contoh Sederhana: useToggle
Custom Hook
Mari kita mulai dengan contoh sederhana: membuat hook untuk mengelola nilai boolean yang bisa di-toggle. Ini sering dibutuhkan untuk dropdown, modal, atau visibility elemen.
JavaScript
// useToggle.js import { useState, useCallback } from 'react'; function useToggle(initialValue = false) { const [isOn, setIsOn] = useState(initialValue); // Menggunakan useCallback untuk memastikan fungsi toggle tidak dibuat ulang setiap render const toggle = useCallback(() => { setIsOn(prevIsOn => !prevIsOn); }, []); return [isOn, toggle]; // Mengembalikan state dan fungsi toggle } export default useToggle;
Cara Menggunakan useToggle
di Komponen:
JavaScript
// MyComponent.jsx import React from 'react'; import useToggle from './useToggle'; // Import custom hook Anda function MyComponent() { const [isModalOpen, toggleModal] = useToggle(false); // Gunakan hook return ( <div> <h2>Contoh Penggunaan useToggle</h2> <button onClick={toggleModal}> {isModalOpen ? 'Tutup Modal' : 'Buka Modal'} </button> {isModalOpen && ( <div style={{ border: '1px solid black', padding: '20px', marginTop: '10px', backgroundColor: '#f0f0f0' }}> Ini adalah konten modal! </div> )} {/* Anda bisa menggunakan hook yang sama untuk logic toggle yang berbeda */} <hr style={{margin: '20px 0'}} /> <InternalSection /> </div> ); } function InternalSection() { const [isSectionVisible, toggleSection] = useToggle(true); // Penggunaan lain dari useToggle return ( <div> <h3>Bagian Internal</h3> <button onClick={toggleSection}> {isSectionVisible ? 'Sembunyikan Bagian' : 'Tampilkan Bagian'} </button> {isSectionVisible && <p>Konten bagian ini terlihat.</p>} </div> ); } export default MyComponent;
Contoh Lanjutan: useFetch
Custom Hook (Mengambil Data)
Ini adalah kasus penggunaan yang sangat umum untuk Custom Hooks: mengelola logic pengambilan data (data fetching), loading state, dan error handling.
JavaScript
// useFetch.js import { useState, useEffect } from 'react'; function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { setLoading(true); setError(null); // Reset error setiap kali fetch baru try { const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const result = await response.json(); setData(result); } catch (err) { setError(err); } finally { setLoading(false); } }; if (url) { // Pastikan URL ada sebelum fetching fetchData(); } }, [url]); // Dependensi: jalankan ulang ketika URL berubah return { data, loading, error }; } export default useFetch;
Cara Menggunakan useFetch
di Komponen:
JavaScript
// UserProfile.jsx import React from 'react'; import useFetch from './useFetch'; function UserProfile({ userId }) { const { data: user, loading, error } = useFetch( `https://jsonplaceholder.typicode.com/users/${userId}` // Contoh API publik ); if (loading) { return <p>Memuat data pengguna...</p>; } if (error) { return <p>Terjadi kesalahan: {error.message}</p>; } if (!user) { return <p>Pengguna tidak ditemukan.</p>; } return ( <div> <h2>Profil Pengguna</h2> <p><strong>Nama:</strong> {user.name}</p> <p><strong>Email:</strong> {user.email}</p> <p><strong>Website:</strong> {user.website}</p> </div> ); } // App.jsx (Contoh penggunaan UserProfile) import React, { useState } from 'react'; import UserProfile from './UserProfile'; function App() { const [currentUserId, setCurrentUserId] = useState(1); return ( <div> <h1>Aplikasi Pengguna</h1> <button onClick={() => setCurrentUserId(prevId => prevId + 1)}> Muat Pengguna Selanjutnya ({currentUserId + 1}) </button> <UserProfile userId={currentUserId} /> </div> ); } export default App;
Hal-hal Penting untuk Diingat Saat Membuat Custom Hooks:
-
Awali dengan
use
: Ini adalah konvensi penamaan yang wajib agar React mengenali fungsi Anda sebagai hook dan dapat menerapkan Aturan Hooks. -
Panggil Hooks Lain di Dalamnya: Custom Hooks dirancang untuk memanggil hook bawaan React (
useState
,useEffect
,useCallback
,useMemo
,useRef
, dll.) dan/atau Custom Hooks lainnya. -
Kembalikan Apa Pun yang Anda Butuhkan: Custom Hooks dapat mengembalikan state, fungsi, objek, atau apa pun yang Anda inginkan. Biasanya, mereka mengembalikan array (seperti
useState
) atau objek (seperti contohuseFetch
). -
Logika yang Terisolasi: Setiap kali Anda memanggil custom hook di sebuah komponen, state di dalam hook tersebut adalah isolated dan tidak saling memengaruhi antar instance. Misalnya,
isModalOpen
diMyComponent
tidak akan memengaruhiisSectionVisible
diInternalSection
, meskipun keduanya menggunakanuseToggle
. -
Dependensi
useEffect
danuseCallback
: Perhatikan dependensi yang Anda berikan padauseEffect
danuseCallback
di dalam custom hook Anda. Ini penting untuk mencegah infinite loops atau bug terkait stale closures.
Kapan Harus Membuat Custom Hooks?
-
Ketika Anda menemukan diri Anda menulis logic yang sama di beberapa komponen.
-
Ketika logic dalam komponen Anda menjadi terlalu kompleks dan membuat komponen sulit dibaca atau di-maintain.
-
Ketika Anda ingin berbagi logic stateful antar komponen tanpa prop drilling atau HOC yang rumit.
-
Untuk mengelola efek samping (seperti subscriptions, timers, data fetching) yang terkait dengan lifecycle komponen.
Custom Hooks adalah fitur yang revolusioner di React karena mereka mendorong pattern reusability dan separation of concerns yang lebih baik, membuat aplikasi React Anda lebih bersih, lebih terorganisir, dan lebih mudah untuk dikembangkan. Selamat mencoba membuat custom hook Anda sendiri!
0 Komentar
Artikel Terkait
