0
0
Lập trình
Hưng Nguyễn Xuân 1
Hưng Nguyễn Xuân 1xuanhungptithcm

📚 Bảng Tóm Tắt Tối Ưu React Hooks (Phiên Bản 2025)

Đăng vào 5 tháng trước

• 8 phút đọc

📑 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 Copy
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 Copy
const [value, setValue] = useState(initialValue);
  • value → trạng thái hiện tại
  • setValue → hàm để cập nhật trạng thái
  • initialValue → 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 Copy
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 Copy
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 Copy
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 Copy
const value = useContext(MyContext);
  • MyContext → đối tượng context bạn đã tạo bằng React.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 Copy
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 Copy
const [state, dispatch] = useReducer(reducerFn, initialState);
  • state → trạng thái hiện tại
  • dispatch → hàm để gửi action
  • reducerFn(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 Copy
const memoizedHandler = useCallback(() => {
  console.log("Chạy chỉ khi dependencies thay đổi");
}, [dependency]);

API Sử Dụng:

javascript Copy
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 Copy
const expensiveValue = useMemo(() => heavyCalculation(data), [data]);

API Sử Dụng:

javascript Copy
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 Copy
const inputRef = useRef(null);

<input ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>
  Tập trung vào input
</button>

API Sử Dụng:

javascript Copy
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 Copy
useImperativeHandle(ref, () => ({
  focus: () => inputRef.current.focus()
}));

API Sử Dụng:

javascript Copy
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 Copy
useLayoutEffect(() => {
  console.log("DOM đã sẵn sàng, trước khi vẽ");
}, []);

API Sử DỤng:

javascript Copy
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 Copy
function useFriendStatus(friendID) {
  const isOnline = useSomeCustomHook(friendID);
  useDebugValue(isOnline ? "Online" : "Offline");
  return isOnline;
}

API Sử Dụng:

javascript Copy
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 Copy
const id = useId();

<label htmlFor={id}>Tên</label>
<input id={id} />

API Sử Dụng:

javascript Copy
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ính aria-*)

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 Copy
const [isPending, startTransition] = useTransition();

startTransition(() => {
  setList(hugeNewList);
});

isPending && <Spinner />

API Sử Dụng:

javascript Copy
const [isPending, startTransition] = useTransition();
  • isPending → true trong khi đang xảy ra chuyển tiếp
  • startTransition(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 Copy
const deferredSearch = useDeferredValue(searchQuery);

useEffect(() => {
  fetchData(deferredSearch);
}, [deferredSearch]);

API Sử Dụng:

javascript Copy
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 Copy
const state = useSyncExternalStore(
  store.subscribe,
  store.getSnapshot
);

API Sử Dụng:

javascript Copy
const state = useSyncExternalStore(subscribeFn, getSnapshotFn);
  • subscribeFn → được gọi để lắng nghe thay đổi
  • getSnapshotFn → 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 Copy
useInsertionEffect(() => {
  injectStyles(".btn { color: red }");
}, []);

API Sử Dụng:

javascript Copy
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 Copy
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 Copy
const [value, toggle] = useToggle(initialValue);
  • value → trạng thái hiện tại
  • toggle() → 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 Copy
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.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào