Reactjs Custom Hooks State Sharing Patterns
Selesai membaca dokumentasi ini?
Kembali ke rujukan utama React.js untuk melanjutkan topik lainnya.
Kembali ke rujukan utama React.js untuk melanjutkan topik lainnya.
Custom hook adalah function JavaScript biasa yang diawali dengan use dan di dalamnya memakai hook React lain untuk mengekstrak logic yang bisa dipakai ulang. Tujuannya bukan membuat abstraksi yang keren-kerenan, tapi membuat komponen tetap tipis, fokus ke UI, dan mudah dirawat.
Di topik ini ada dua hal yang sering nyambung:
Kalau disederhanakan, custom hook menjawab pertanyaan: “logic ini sebaiknya diletakkan di mana?”. Sedangkan state sharing patterns menjawab: “state ini harus tinggal di mana, dan siapa yang boleh ikut membaca atau mengubahnya?”
Buat custom hook kalau logic yang sama mulai muncul berulang, tetapi UI-nya tetap berbeda.
Prinsip amannya begini: kalau logic itu punya lifecycle React atau bergantung pada hook lain, custom hook masuk akal. Kalau logic-nya murni transformasi data tanpa state atau effect, fungsi biasa sering lebih tepat.
Tujuan utama custom hook adalah memisahkan mekanisme dari representasi.
Dengan begitu, komponen tidak perlu tahu detail cara data diambil, cara retry dijalankan, atau cara subscription dibersihkan. Komponen cukup menerima hasil akhir dari hook.
import { useUsers } from './useUsers';
function UsersPage() {
const { users, loading, error, refetch } = useUsers();
if (loading) return <p>Memuat data...</p>;
if (error) return <button onClick={refetch}>Coba lagi</button>;
return
Di contoh ini:
UsersPage fokus ke tampilan.useUsers fokus ke pengambilan data dan state lifecycle.Alur ini membantu menjaga satu aturan sederhana: komponen membaca hasil, hook mengurus proses.
Custom hook yang bagus biasanya punya batas yang jelas.
useState untuk menyimpan state lokal.useEffect untuk side effect.useMemo dan useCallback kalau memang perlu stabilitas referensi atau hasil hitung.Biasanya hook mengembalikan object agar mudah dibaca saat destructuring:
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const open = () => setValue(true);
const close = () =>
Output seperti ini enak dipakai ulang karena consumer tidak perlu tahu implementasi internalnya.
Berbagi state itu bukan selalu berarti memakai global state. Dalam banyak kasus, masalahnya selesai dengan memindahkan state ke tempat yang paling tepat.
Kalau state cuma dipakai satu komponen, tetap lokal saja.
Contoh:
Ini pilihan paling sederhana dan paling mudah di-debug.
Kalau dua atau lebih komponen butuh state yang sama, naikkan state ke parent terdekat yang relevan.
function SearchPanel() {
const [query, setQuery] = useState('');
return (
<>
<SearchInput value={query} onChange={setQuery} />
<SearchResult query={query} />
Pola ini cocok kalau:
Kadang state sharing masih lokal, tapi logic-nya terlalu berat kalau ditaruh langsung di komponen parent. Di sini custom hook membantu.
function useSearchPanel() {
const [query, setQuery] = useState('');
const [filters, setFilters] = useState([]);
return {
query,
Ini membuat parent tetap ramping, sementara state logic terkumpul di satu tempat.
Kalau state perlu diakses banyak komponen di level berbeda, Context bisa jadi pilihan.
Gunakan Context kalau:
Tapi tetap hati-hati: Context bukan alasan untuk memindahkan semua state ke atas. Kalau terlalu luas, satu perubahan kecil bisa memicu rerender yang tidak perlu.
Ini pola yang cukup sehat kalau kita ingin logic dan akses state sama-sama rapi.
Pola ini cocok untuk area aplikasi yang memang punya shared state, misalnya auth session, theme, cart, atau sidebar state.
Kalau kebutuhan belum sampai sana, jangan lompat ke store terlalu cepat. Biasanya justru custom hook + lift state up sudah cukup.
function useUsers() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error
Poin pentingnya:
function useModalState() {
const [isOpen, setIsOpen] = useState(false);
const open = useCallback(() => setIsOpen(true), []);
const close = useCallback(()
Kalau modal dipakai bersama beberapa tombol dan header action, hook ini menjaga logika tetap konsisten.
Kalau hook mulai berisi terlalu banyak tanggung jawab, pecah menjadi beberapa hook yang lebih spesifik.
Tanda-tandanya:
Kalau hanya dipakai satu komponen dan tidak mengurangi kompleksitas, mungkin hook itu belum perlu.
Context bukan tempat parkir semua state. Gunakan hanya kalau kebutuhan berbagi memang nyata.
Kalau komponen masih penuh dengan useEffect, fetch, setState, dan conditional logic, kemungkinan pemisahan belum selesai.
Membuat custom hook sebelum pola reuse-nya jelas sering menghasilkan nama yang ragu-ragu dan API yang kurang pas.
useState, useEffect, useMemo, useCallback, dan useRef