7 Custom Hooks React Quan Trọng Mà Bạn Cần Nắm Vững Trong Lập Trình Front-End
Custom hooks không chỉ là một công cụ mạnh mẽ trong React mà còn là yếu tố then chốt giúp lập trình viên viết mã hiệu quả, dễ bảo trì và tái sử dụng. Những hooks này cho phép bạn đóng gói logic phức tạp, quản lý trạng thái và tối ưu hóa trải nghiệm người dùng một cách tối đa.
Bài viết này sẽ giới thiệu 7 custom hooks thiết yếu mà mọi lập trình viên Front-End nên có trong bộ công cụ của mình, cùng với hướng dẫn chi tiết để triển khai chúng một cách hiệu quả.
1. useFetch: Đơn Giản Hóa Các Lệnh Gọi API
Lấy dữ liệu là một tác vụ phổ biến trong React. Hook useFetch
sẽ giúp bạn tóm tắt và tối ưu logic lặp đi lặp lại, quản lý lời gọi API và trạng thái một cách hiệu quả.
Cách thực hiện:
javascript
import { useState, useEffect } from "react";
function useFetch<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const response = await fetch(url);
const result = await response.json();
setData(result);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetch;
Cách sử dụng:
javascript
const { data, loading, error } = useFetch<User[]>('/api/users');
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return <ul>{data?.map(user => <li key={user.id}>{user.name}</li>)}</ul>;
2. useDebounce: Tối Ưu Hiệu Suất Nhập Liệu
Khi xử lý input từ người dùng, như tìm kiếm hay các trường biểu mẫu, useDebounce
giúp giảm thiểu số lần render và gọi API không cần thiết, cải thiện hiệu suất ứng dụng.
Cách thực hiện:
javascript
import { useState, useEffect } from "react";
function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
export default useDebounce;
Cách sử dụng:
javascript
const [searchTerm, setSearchTerm] = useState('');
const debouncedSearch = useDebounce(searchTerm, 500);
useEffect(() => {
if (debouncedSearch) {
// Gọi API hoặc thực hiện hành động khác
}
}, [debouncedSearch]);
3. useToggle: Dễ Dàng Quản Lý Trạng Thái Boolean
Hook useToggle
giúp bạn dễ dàng quản lý trạng thái mở/đóng cho các modal, dropdown hoặc chuyển đổi theme, làm cho mã trở nên gọn gàng và dễ tái sử dụng.
Cách thực hiện:
javascript
import { useState } from "react";
function useToggle(initialState = false) {
const [state, setState] = useState(initialState);
const toggle = () => setState(prev => !prev);
return [state, toggle] as const;
}
export default useToggle;
Cách sử dụng:
javascript
const [isModalOpen, toggleModal] = useToggle();
return (
<div>
<button onClick={toggleModal}>Toggle Modal</button>
{isModalOpen && <p>Nội Dung Modal</p>}
</div>
);
4. useLocalStorage: Lưu Trữ Dữ Liệu Cục Bộ Một Cách Dễ Dàng
Hook useLocalStorage
cho phép bạn lưu trữ và lấy dữ liệu từ localStorage một cách hiệu quả và dễ sử dụng.
Cách thực hiện:
javascript
import { useState } from "react";
function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
});
const setValue = (value: T) => {
try {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(error);
}
};
return [storedValue, setValue] as const;
}
export default useLocalStorage;
Cách sử dụng:
javascript
const [theme, setTheme] = useLocalStorage('theme', 'light');
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>Toggle Theme</button>
);
5. usePrevious: Theo Dõi Trạng Thái Trước Đó
Để thực hiện các hiệu ứng hoạt hình hoặc so sánh trạng thái, việc theo dõi trạng thái trước đó là rất cần thiết. Hook usePrevious
giúp bạn một cách đơn giản.
Cách thực hiện:
javascript
import { useEffect, useRef } from "react";
function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
export default usePrevious;
Cách sử dụng:
javascript
const [count, setCount] = useState(0);
const prevCount = usePrevious(count);
return (
<p>Bây giờ: {count}, Trước đó: {prevCount}</p>
);
6. useClickOutside: Phát Hiện Click Ra Ngoài
Hook useClickOutside
rất hữu ích để phát hiện và đóng các modal hoặc dropdown khi người dùng click bên ngoài chúng, cải thiện trải nghiệm người dùng.
Cách thực hiện:
javascript
import { useEffect, useRef } from "react";
function useClickOutside(handler: () => void) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (ref.current && !ref.current.contains(event.target as Node)) {
handler();
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, [handler]);
return ref;
}
export default useClickOutside;
Cách sử dụng:
javascript
const ref = useClickOutside(() => setDropdownOpen(false));
return (
<div ref={ref}>
{dropdownOpen && <p>Nội Dung Dropdown</p>}
</div>
);
7. useMediaQuery: Xử Lý Thiết Kế Responsive
Quản lý media queries trong React đã trở nên dễ dàng hơn với hook useMediaQuery
, giúp các nhà phát triển tạo ra thiết kế responsive một cách hiệu quả.
Cách thực hiện:
javascript
import { useState, useEffect } from "react";
function useMediaQuery(query: string): boolean {
const [matches, setMatches] = useState(false);
useEffect(() => {
const mediaQueryList = window.matchMedia(query);
const updateMatch = () => setMatches(mediaQueryList.matches);
updateMatch();
mediaQueryList.addEventListener('change', updateMatch);
return () => mediaQueryList.removeEventListener('change', updateMatch);
}, [query]);
return matches;
}
export default useMediaQuery;
Cách sử dụng:
javascript
const isMobile = useMediaQuery('(max-width: 768px)');
return <p>{isMobile ? 'Giao Diện Di Động' : 'Giao Diện Máy Tính'}</p>;
Kết Luận
Custom hooks không chỉ thể hiện sự linh hoạt của React mà còn giúp lập trình viên viết mã sạch hơn, dễ bảo trì và tái sử dụng. Bằng cách áp dụng các custom hooks vừa được giới thiệu, bạn có thể giảm thiểu độ phức tạp trong mã nguồn của mình và nâng cao hiệu suất tổng thể của ứng dụng. Hy vọng bài viết này sẽ giúp ích cho bạn trong hành trình phát triển ứng dụng với React!
source: viblo