0
0
Lập trình
Admin Team
Admin Teamtechmely

Nắm Vững Quy Tắc React Hooks: Từ Cơ Bản Đến Nâng Cao

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

• 4 phút đọc

React Hooks là một trong những tính năng mạnh mẽ nhất trong React, cho phép chúng ta tái sử dụng logic trạng thái một cách tinh tế. Tuy nhiên, với sức mạnh lớn đi kèm là những quy tắc nghiêm ngặt. Việc vi phạm những quy tắc này sẽ dẫn đến những lỗi khó hiểu — kiểu lỗi mà khiến bạn phải vò đầu bứt tai lúc 2 giờ sáng.

Trong bài viết này, chúng ta sẽ đi sâu vào Quy Tắc của Hooks, khám phá những điều cần làm và không nên làm, và kết thúc với những mẹo từ chuyên gia để bạn có thể viết mã React vững chắc.


🔹 Hooks Là Gì?

Hooks là những hàm JavaScript đặc biệt (như useState, useEffect, useContext) cho phép bạn "kết nối" với các tính năng nội bộ của React.

✅ Chúng luôn bắt đầu bằng use.
✅ Chúng phải được gọi trong khi React đang render một component chức năng.


🔹 Hai Quy Tắc Vàng Của Hooks

1. Gọi Hooks Ở Cấp Độ Cao Nhất

Không bao giờ gọi Hooks bên trong các vòng lặp, điều kiện, hàm lồng nhau, hoặc try/catch.

✔️ Tốt:

javascript Copy
function Counter() {
  const [count, setCount] = useState(0); // ✅ Luôn ở đầu
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

❌ Xấu:

javascript Copy
function Bad({ cond }: { cond: boolean }) {
  if (cond) {
    const theme = useContext(ThemeContext); // 🔴 Sai: bên trong điều kiện
  }
}

2. Gọi Hooks Chỉ Từ Các Hàm React

Hooks chỉ nên được gọi:

  • Từ các component chức năng React
  • Từ Custom Hooks

✔️ Tốt:

javascript Copy
function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  return width;
}

❌ Xấu:

javascript Copy
function randomUtility() {
  const [online, setOnline] = useState(true); // 🔴 Sai: không phải là component hoặc custom hook
}

🔹 Những Sai Lầm Thông Thường (và Cách Khắc Phục)

Dưới đây là những cạm bẫy điển hình mà các nhà phát triển thường gặp phải:

  • Bên trong điều kiện:
javascript Copy
if (loggedIn) {
  const user = useState(null); // ❌ Sai
}

✔️ Cách Khắc Phục: Di chuyển nó lên đầu component.


  • Bên trong vòng lặp:
javascript Copy
for (let i = 0; i < 3; i++) {
  const theme = useContext(ThemeContext); // ❌ Sai
}

✔️ Cách Khắc Phục: Gọi nó một lần ở đầu.


  • Bên trong các hàm xử lý sự kiện:
javascript Copy
function handleClick() {
  const theme = useContext(ThemeContext); // ❌ Sai
}

✔️ Cách Khắc Phục: Di chuyển cuộc gọi hook ra ngoài hàm xử lý.


  • Bên trong các component class:
javascript Copy
class Bad extends React.Component {
  render() {
    useEffect(() => {}); // ❌ Sai
  }
}

✔️ Cách Khắc Phục: Viết lại dưới dạng một component chức năng.


  • Bên trong các callback của useMemo / useReducer:
javascript Copy
const style = useMemo(() => {
  const theme = useContext(ThemeContext); // ❌ Sai
  return createStyle(theme);
}, []);

✔️ Cách Khắc Phục: Gọi useContext bên ngoài useMemo.


  • Bên trong try/catch:
javascript Copy
try {
  const [x, setX] = useState(0); // ❌ Sai
} catch {
  const [y, setY] = useState(1); // ❌ Sai
}

✔️ Cách Khắc Phục: Luôn gọi hooks một cách không điều kiện ở cấp độ cao nhất.


🔹 Công Cụ: Phát Hiện Lỗi Sớm

Sử dụng plugin ESLint eslint-plugin-react-hooks để tự động phát hiện các vi phạm:

shell Copy
npm install eslint-plugin-react-hooks --save-dev

Tập tin .eslintrc.json:

json Copy
{
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
  }
}

🔹 Tại Sao Những Quy Tắc Này Tồn Tại?

React dựa vào thứ tự của các cuộc gọi Hook.
Nếu bạn gọi hooks có điều kiện, React không thể đảm bảo trạng thái nào thuộc về cuộc gọi nào, gây ra những lỗi gần như không thể gỡ lỗi.

Bằng cách thực thi những quy tắc này:

  • Hooks luôn chạy theo cùng một thứ tự.
  • React có thể theo dõi trạng thái một cách nhất quán qua các lần render.

🔹 Mẹo Chuyên Gia 🚀

  • ✅ Sử dụng custom hooks để bao gói logic chia sẻ (useAuth, useFetch, v.v.)
  • ✅ Kết hợp Hooks với giao diện TypeScript để đảm bảo an toàn kiểu.
  • ✅ Ưu tiên null unions (User | null) khi trạng thái có thể chưa tồn tại.
  • ✅ Sử dụng render có điều kiện thay vì cuộc gọi hook có điều kiện.

🏁 Kết Luận

Hooks là một bước ngoặt — nhưng chỉ khi bạn tôn trọng các quy tắc của chúng.
Bằng cách luôn gọi hooks ở cấp độ cao nhấtchỉ bên trong các hàm React, bạn đảm bảo rằng các component của bạn luôn có thể dự đoán, an toàn kiểu và sẵn sàng cho sản xuất.

Lần tới khi bạn gặp lỗi như:

“Cuộc gọi hook không hợp lệ”

...có lẽ bạn đã vi phạm một trong những quy tắc này.

Hãy giữ kỷ luật, và các ứng dụng React + TypeScript của bạn sẽ sạch sẽ, mạnh mẽ và dễ dàng mở rộng.

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