Pendahuluan
React Hooks telah merevolusi cara kami menulis komponen React sejak diperkenalkan di versi 16.8. Namun, banyak developer yang masih menggunakan hook hanya pada tingkat permukaan, tanpa menyadari pola kuat yang diaktifkannya.
Artikel ini mengeksplorasi pola React Hooks tingkat lanjut yang dapat secara signifikan meningkatkan kualitas, kinerja, dan skalabilitas aplikasi React Anda.
Hook Kustom yang Kuat
useFetchdengan Manajemen Cache
import { useState, useEffect, useRef } dari "react";
const useFetch = (url, opsi = {}) => {
const [data, setData] = useState(null);
const [memuat, setLoading] = useState(true);
const [kesalahan, setError] = useState(null);
const cache = useRef({});
gunakanEffect(() => {
jika (!url) kembali;
const mengambilData = async() => {
setLoading(benar);
setError(nol);
// Mekanisme cache
if (cache.saat ini[url]) {
setData(cache.saat ini[url]);
setLoading(salah);
kembali;
}
coba {
const respon = menunggu pengambilan(url, opsi);
if (!response.ok) throw new Error("Respon jaringan tidak baik");
hasil const = menunggu respon.json();
cache.current[url] = hasil;
setData(hasil);
} menangkap (salah) {
setError(err.pesan);
} akhirnya {
setLoading(salah);
}
};
ambilData();
}, [url]);
return { data, memuat, kesalahan };
};
2. useLocalStorage dengan Serialisasi
impor { useState } dari "react";
const useLocalStorage = (kunci, Nilai awal) => {
const [nilai tersimpan, setnilai tersimpan] = useState(() => {
coba {
const item = window.localStorage.getItem(kunci);
barang kembalian? JSON.parse(item): Nilai awal;
} tangkapan (kesalahan) {
console.error(`Kesalahan membaca kunci Penyimpanan lokal "${key}":`, kesalahan);
kembalikan Nilai Awal;
}
});
const setValue = (nilai) => {
coba {
const valueToStore = nilai instanceof Fungsi? nilai(nilai tersimpan): nilai;
setStoredValue(nilaiToStore);
window.localStorage.setItem(kunci, JSON.stringify(valueToStore));
} tangkapan (kesalahan) {
console.error(`Kesalahan saat menyetel kunci Penyimpanan lokal "${key}":`, kesalahan);
}
};
kembali [nilai tersimpan, nilai set];
};
useReducer untuk Manajemen Status Kompleks
Aplikasi Todo Tingkat Lanjut dengan useReducer
const todoReducer = (state, action) => {
beralih (tipe tindakan) {
kasus "ADD_TODO":
kembali {
...negara bagian,
semua yang harus dilakukan: [
...negara.todos,
{
id: Tanggal.sekarang(),
teks: aksi.payload,
selesai: salah,
dibuatPada: Tanggal baru().toISOString(),
},
],
};
kasus "TOGGLE_TODO":
kembali {
...negara bagian,
semua yang harus dilakukan: state.todos.map((todo) =>
todo.id === aksi.payload
? { ...todo, selesai: !todo.selesai }
: melakukan
),
};
kasus "DELETE_TODO":
kembali {
...negara bagian,
todos: state.todos.filter((todo) => todo.id !== action.payload),
};
kasus "SET_FILTER":
return { ...state, filter: action.payload };
kasus "BULK_UPDATE":
kembali {
...negara bagian,
hal yang harus dilakukan: state.todos.map((hal yang harus dilakukan) => ({
... yang harus dilakukan,
...aksi.payload.pembaruan,
})),
};
bawaan:
negara bagian kembali;
}
};
const useTodo = () => {
const [negara bagian, pengiriman] = useReducer(todoReducer, {
semua yang harus dilakukan: [],
menyaring: "semua",
});
const filteredTodos = state.todos.filter((todo) => {
beralih (status.filter) {
kasus "selesai":
return todo.selesai;
kasus "aktif":
kembali !todo.selesai;
bawaan:
kembali benar;
}
});
kembali {
semua yang dilakukan: difilterTodos,
addTodo: (teks) => pengiriman({ ketik: "ADD_TODO", muatan: teks }),
toggleTodo: (id) => pengiriman({ ketik: "TOGGLE_TODO", muatan: id }),
deleteTodo: (id) => pengiriman({ ketik: "DELETE_TODO", muatan: id }),
setFilter: (filter) => pengiriman({ ketik: "SET_FILTER", muatan: filter }),
};
};
Teknik Optimasi yang Jarang Diketahui
1. useMemo dengan Perbandingan Mendalam
impor { useMemo, useRef } dari "react";
const useDeepCompareMemo = (pabrik, dependensi) => {
const ref = gunakanRef();
const serializedDeps = JSON.stringify(dependensi);
kembalikan useMemo(() => {
if (ref.saat ini !== serializedDeps) {
ref.saat ini = serializedDeps;
kembalikan pabrik();
}
}, [serializedDeps, pabrik]);
};
2. useCallback dengan Injeksi Ketergantungan
impor { useCallback, useEffect, useRef } dari "react";
const useStableCallback = (panggilan balik, dependensi = []) => {
const callbackRef = useRef(panggilan balik);
gunakanEffect(() => {
callbackRef.current = panggilan balik;
});
kembalikan useCallback((...args) => {
return callbackRef.saat ini(...args);
}, dependensi);
};
Pola Tingkat Lanjut: Komponen Gabungan dengan Konteks
import { createContext, useContext, useState } dari "react";
const AccordionContext = buatContext();
const Akordeon = ({ anak, kelipatan = salah }) => {
const [Item terbuka, setItem Terbuka] = useState([]);
const toggleItem = (id) => {
setOpenItems((sebelumnya) =>
banyak
? sebelumnya.termasuk(id)
? sebelumnya.filter((i) => saya !== id)
: [...sebelumnya, identitas]
: sebelumnya.termasuk(id)
? []
: [id]
);
};
kembali (
<AccordionContext.Provider value={{ openItems, toggleItem }}>
{anak-anak}
</AccordionContext.Penyedia>
);
};
Pola: Mesin Status dengan useReducer
const createMachine = (config) => (state, action) => {
const saat ini = config.states[state.state];
if (saat ini?.transisi?.[action.type]) {
const transisi = arus.transisi[tindakan.tipe];
kembali {
status: transisi.target,
konteks:
transisi.aksi?.(status.konteks, tindakan) ?? negara.konteks,
};
}
negara bagian kembali;
};
Praktik dan Kesalahan Terbaik
1. Array Ketergantungan Kait
// ❌ Salah
useEffect(() => {}, [props.pengguna]);
// ✅ Benar
useEffect(() => {}, [props.pengguna.id]);
2. Komposisi Kait Khusus
const useUserDashboard = (userId) => {
const pengguna = useUser(userId);
const posting = useUserPosts(userId);
pemberitahuan const = useUserNotifications(userId);
const sedang Memuat =
pengguna.memuat || posting.memuat || notifikasi.memuat;
kembali {
pengguna: pengguna.data,
postingan: postingan.data,
notifikasi: notifikasi.data,
sedang memuat,
};
};
3. Penanganan Kesalahan dengan Hooks
import { useCallback, useEffect, useState } from "react";
const useErrorHandler = () => {
const [kesalahan, setError] = useState(null);
const handleError = useCallback((err) => {
console.error("Kesalahan aplikasi:",err);
setError(salah);
}, []);
gunakanEffect(() => {
jika (kesalahan) melempar kesalahan;
}, [kesalahan]);
kembalikan handleError;
};
Kesimpulan
Pola React Hooks tingkat lanjut membuka cara ampuh untuk membangun aplikasi yang dapat dikelola, berperforma, dan dapat diskalakan.
Poin Penting
Hook khusus meningkatkan penggunaan kembali logika dan pemisahan masalah
useReducermenyederhanakan manajemen status yang kompleksMemoisasi tingkat lanjut meningkatkan kinerja
Komponen gabungan memungkinkan API yang fleksibel
Mesin status menciptakan transisi status yang dapat diprediksi
Dengan menguasai pola-pola ini, Anda akan menjadi developer React yang lebih percaya diri dan efektif.