📑 Mục Lục
-
Các Hook Cơ Bản (cần biết)
-
useState- hộp lưu trữ mini của bạn -
useEffect- quản lý tác dụng phụ -
useContext- không còn đau đầu với prop-drilling
-
-
Hook Bổ Sung (tối ưu hóa & trạng thái phức tạp)
-
useReducer- máy trạng thái -
useCallback- hàm đã ghi nhớ -
useMemo- giá trị đã ghi nhớ -
useRef- hộp lưu trữ bền vững -
useImperativeHandle- API ref tùy chỉnh -
useLayoutEffect- tác dụng đồng bộ -
useDebugValue- trợ giúp công cụ phát triển
-
-
Hook React 18+ (mới & sáng bóng)
-
useId- ID duy nhất không đau đầu -
useTransition- cập nhật trạng thái mượt mà -
useDeferredValue- hoãn cập nhật chậm -
useSyncExternalStore- đăng ký bên ngoài an toàn -
useInsertionEffect- tiêm kiểu trước khi vẽ
-
-
Hook Tùy Chỉnh – vũ khí bí mật của bạn
-
Ví dụ
useToggle -
Ví dụ
useLocalStorage
-
-
Kết Luận – bảng tóm tắt React Hooks của bạn
Chào mừng bạn đến với bảng tóm tắt tối ưu về React Hooks! Nếu bạn là một nhà phát triển web, việc nắm vững các hook này sẽ giúp bạn dễ dàng quản lý trạng thái và xử lý các tác dụng phụ trong ứng dụng React của mình. Hãy cùng khám phá từng hook một cách chi tiết!
🟢 Các Hook Cơ Bản (cần biết)
useState - hộp lưu trữ mini của bạn
useState cho phép bạn lưu trữ trạng thái trong một component. Hãy xem ví dụ sau:
javascript
const [count, setCount] = useState(0);
<button onClick={() => setCount(count + 1)}>
Bạn đã nhấn {count} lần
</button>
Khi gọi
setCount, React sẽ re-render component với giá trị mới.
API Sử Dụng:
javascript
const [value, setValue] = useState(initialValue);
value→ trạng thái hiện tạisetValue→ hàm để cập nhật trạng tháiinitialValue→ giá trị khởi tạo
useEffect - quản lý tác dụng phụ
useEffect cho phép bạn thực hiện tác dụng phụ sau khi component đã được render. Ví dụ:
javascript
useEffect(() => {
console.log("Component đã được mount hoặc cập nhật!");
return () => {
console.log("Dọn dẹp trước khi unmount hoặc chạy lần tiếp theo");
};
}, [/* dependencies ở đây */]);
Thêm dependencies vào mảng để kiểm soát khi nào nó chạy. Để mảng trống (
[]) nếu bạn chỉ muốn nó chạy một lần khi mount.
API Sử Dụng:
javascript
useEffect(() => {
// tác dụng phụ
return () => { /* dọn dẹp */ }
}, [dependencies]);
- Chạy sau mỗi lần render trừ khi bạn kiểm soát bằng dependencies
- Mảng rỗng (
[]) → chỉ chạy một lần [dep1, dep2]→ chạy khi những giá trị này thay đổi
useContext - không còn đau đầu với prop-drilling
Nếu bạn mệt mỏi vì phải truyền props qua nhiều cấp độ, useContext cho phép bạn truy cập dữ liệu từ context. Ví dụ:
javascript
const ThemeContext = React.createContext("light");
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <button className={theme}>Tôi đang ở chế độ {theme}</button>;
}
Sử dụng khi nhiều component cần dữ liệu giống nhau (chủ đề, người dùng, ngôn ngữ, v.v.)
API Sử Dụng:
javascript
const value = useContext(MyContext);
MyContext→ đối tượng context bạn đã tạo bằngReact.createContext.value→ giá trị mà Provider gần nhất cung cấp cho bạn.
⚡ Hook Bổ Sung (tối ưu hóa & trạng thái phức tạp)
useReducer - máy trạng thái
Khi logic trạng thái trở nên phức tạp, useReducer là lựa chọn tuyệt vời. Nó tương tự như useState nhưng mạnh mẽ hơn. Ví dụ:
javascript
function reducer(state, action) {
switch (action.type) {
case "increment": return { count: state.count + 1 };
case "decrement": return { count: state.count - 1 };
default: return state;
}
}
const [state, dispatch] = useReducer(reducer, { count: 0 });
<button onClick={() => dispatch({ type: "increment" })}>
{state.count}
</button>
API Sử Dụng:
javascript
const [state, dispatch] = useReducer(reducerFn, initialState);
state→ trạng thái hiện tạidispatch→ hàm để gửi actionreducerFn(state, action)→ quyết định cách trạng thái thay đổi
useCallback - hàm đã ghi nhớ
useCallback giúp ghi nhớ hàm để tránh việc re-render không cần thiết. Ví dụ:
javascript
const memoizedHandler = useCallback(() => {
console.log("Chạy chỉ khi dependencies thay đổi");
}, [dependency]);
API Sử Dụng:
javascript
const memoizedFn = useCallback(fn, [dependencies]);
- Trả về cùng một instance hàm trừ khi dependencies thay đổi
- Rất tốt cho tối ưu hóa hiệu suất
useMemo - giá trị đã ghi nhớ
Đối với những tính toán tốn kém, hãy bọc chúng trong useMemo để không phải tính toán lại mỗi lần render.
javascript
const expensiveValue = useMemo(() => heavyCalculation(data), [data]);
API Sử Dụng:
javascript
const memoizedValue = useMemo(calcFn, [dependencies]);
- Chỉ tái tính toán nếu dependencies thay đổi
- Nghĩa là kết quả đã được cached
useRef - hộp lưu trữ bền vững
useRef giúp giữ giá trị qua các lần render mà không thay đổi. Ví dụ:
javascript
const inputRef = useRef(null);
<input ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>
Tập trung vào input
</button>
API Sử Dụng:
javascript
const ref = useRef(initialValue);
ref.current→ giá trị có thể thay đổi (node DOM hoặc giá trị tùy chỉnh)
useImperativeHandle - API ref tùy chỉnh
Khi bạn muốn một parent gọi phương thức trên child, sử dụng useImperativeHandle với forwardRef.
javascript
useImperativeHandle(ref, () => ({
focus: () => inputRef.current.focus()
}));
API Sử Dụng:
javascript
useImperativeHandle(ref, () => customObject, [dependencies]);
- Được sử dụng với
forwardRef - Cho phép parent gọi các phương thức như
childRef.current.doSomething()
useLayoutEffect - tác dụng đồng bộ
Tương tự như useEffect nhưng chạy đồng bộ sau khi DOM đã thay đổi (trước khi trình duyệt vẽ). Ví dụ:
javascript
useLayoutEffect(() => {
console.log("DOM đã sẵn sàng, trước khi vẽ");
}, []);
API Sử DỤng:
javascript
useLayoutEffect(effectFn, [dependencies]);
- Chặn việc vẽ cho đến khi nó hoàn thành (⚠️ sử dụng cẩn thận)
useDebugValue – trợ giúp công cụ phát triển
Dùng trong các hook tùy chỉnh để dán nhãn giá trị trong React DevTools. Chỉ dành cho mã gỡ lỗi.
javascript
function useFriendStatus(friendID) {
const isOnline = useSomeCustomHook(friendID);
useDebugValue(isOnline ? "Online" : "Offline");
return isOnline;
}
API Sử Dụng:
javascript
useDebugValue(value, formatFn?);
- Hiển thị thông tin bổ sung trong React DevTools
🧪 Hook React 18+ (mới & sáng bóng)
useId – ID duy nhất không đau đầu
Cần ID ổn định cho truy cập hoặc biểu mẫu? useId tạo ID duy nhất mà không thay đổi qua các lần render.
javascript
const id = useId();
<label htmlFor={id}>Tên</label>
<input id={id} />
API Sử Dụng:
javascript
const id = useId();
- Trả về một chuỗi duy nhất, ổn định
- Hoàn hảo cho tính năng truy cập (
htmlFor, thuộc tínharia-*)
useTransition – cập nhật trạng thái mượt mà
Đánh dấu các cập nhật là "không chặn" để giữ cho giao diện người dùng phản hồi trong quá trình render nặng.
javascript
const [isPending, startTransition] = useTransition();
startTransition(() => {
setList(hugeNewList);
});
isPending && <Spinner />
API Sử Dụng:
javascript
const [isPending, startTransition] = useTransition();
isPending→ true trong khi đang xảy ra chuyển tiếpstartTransition(callback)→ bao bọc các cập nhật có thể bị trì hoãn
useDeferredValue - hoãn cập nhật chậm
Giảm thiểu giao diện của bạn bằng cách hoãn các cập nhật không quan trọng.
javascript
const deferredSearch = useDeferredValue(searchQuery);
useEffect(() => {
fetchData(deferredSearch);
}, [deferredSearch]);
API Sử Dụng:
javascript
const deferredValue = useDeferredValue(value);
- Trả về một phiên bản cập nhật chậm hơn của giá trị
- Hữu ích cho danh sách lớn, tự động hoàn thành hoặc lọc
useSyncExternalStore - đăng ký bên ngoài an toàn
Đăng ký các kho bên ngoài như Redux hoặc các kho tùy chỉnh một cách an toàn, với React 18’s concurrent rendering.
javascript
const state = useSyncExternalStore(
store.subscribe,
store.getSnapshot
);
API Sử Dụng:
javascript
const state = useSyncExternalStore(subscribeFn, getSnapshotFn);
subscribeFn→ được gọi để lắng nghe thay đổigetSnapshotFn→ trả về trạng thái hiện tại- Xử lý cập nhật đồng thời một cách an toàn
useInsertionEffect – tiêm kiểu trước khi vẽ
Chủ yếu dành cho các thư viện CSS-in-JS. Chạy trước khi thay đổi DOM, đảm bảo kiểu dáng được áp dụng trước khi render.
javascript
useInsertionEffect(() => {
injectStyles(".btn { color: red }");
}, []);
API Sử Dụng:
javascript
useInsertionEffect(effectFn, [dependencies]);
- Chạy đồng bộ trước khi vẽ
- Tuyệt vời cho các thư viện kiểu dáng cần tiêm CSS
🛠️ Hook Tùy Chỉnh – vũ khí bí mật của bạn
Hook tùy chỉnh là các hàm sử dụng các hook khác. Chúng cho phép bạn tái sử dụng logic giữa các component mà không cần lặp lại. Hãy xem ví dụ:
javascript
function useToggle(initial = false) {
const [value, setValue] = useState(initial);
const toggle = () => setValue(v => !v);
return [value, toggle];
}
// Sử dụng trong một component
function App() {
const [isOpen, toggleOpen] = useToggle(false);
return <button onClick={toggleOpen}>{isOpen ? "Mở" : "Đóng"}</button>;
}
API Sử Dụng:
javascript
const [value, toggle] = useToggle(initialValue);
value→ trạng thái hiện tạitoggle()→ chuyển đổi trạng thái từ true → false hoặc false → true
Ví dụ: useLocalStorage – trạng thái tồn tại qua lần làm mới
javascript
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
return JSON.parse(localStorage.getItem(key)) ?? initialValue;
});
const setValue = (value) => {
setStoredValue(value);
localStorage.setItem(key, JSON.stringify(value));
};
return [storedValue, setValue];
}
// Sử dụng
const [name, setName] = useLocalStorage("name", "Khách");
Kết Luận – bảng tóm tắt React Hooks của bạn
Và đó là tất cả! 🎉 Bạn đã có một tham khảo một điểm cho tất cả các hook trong React — từ những điều cơ bản đến những tính năng mới mẻ trong React 18+. Hãy giữ trang này bên cạnh, vì lần tới khi ai đó hỏi về “ví dụ về hook trong React,” bạn chỉ cần mỉm cười và nói, “Tôi đã có rồi.” 😎
Nhớ rằng:
- Hook cơ bản = công cụ hàng ngày của bạn (
useState,useEffect,useContext) - Hook nâng cao = phép thuật tối ưu hóa & trạng thái phức tạp (
useReducer,useCallback,useMemo,useRef) - Hook React 18+ = phép thuật render đồng thời (
useTransition,useDeferredValue,useSyncExternalStore) - Hook tùy chỉnh = vũ khí bí mật của bạn để tái sử dụng logic như một chuyên gia
Nếu bảng tóm tắt này giúp bạn tiết kiệm ngay cả một phút tìm kiếm trên Google, hãy xem xét mời tôi một ly cà phê để tiếp tục duy trì nội dung này: ko-fi.com/deyan_sirakov ☕💖
Giờ thì hãy đi và lập trình như một anh hùng, và đừng quên: React hooks rất mạnh mẽ, nhưng trí nhớ của bạn không cần phải như vậy.