
Custom hook thường được nhắc đến như một “best practice” trong React. Tuy nhiên, không phải cứ thấy logic lặp là tách hook, và cũng không phải hook nào viết ra cũng giúp code tốt hơn. Thực tế, rất nhiều project trở nên khó đọc chỉ vì custom hook được dùng sai mục đích.
Vấn đề cốt lõi không nằm ở cú pháp hay API của React, mà nằm ở cách tư duy khi quyết định tách logic.
1. Custom hook nên dùng khi logic có vòng đời rõ ràng
Trước hết, custom hook phát huy tác dụng tốt nhất khi logic có vòng đời gắn liền với component. Những logic như fetch data, subscribe/unsubscribe, theo dõi sự kiện hoặc đồng bộ state với bên ngoài đều rất phù hợp để đưa vào hook.
Trong những trường hợp này, hook giúp gom toàn bộ logic liên quan vào một chỗ, thay vì rải rác trong useEffect, useState của component. Nhờ đó, component chỉ còn nhiệm vụ render UI.
Nói cách khác, khi logic có điểm bắt đầu, điểm kết thúc và phụ thuộc vào lifecycle của component, custom hook là lựa chọn hợp lý.
2. Custom hook nên dùng khi logic mang tính nghiệp vụ, không phải UI
Tiếp theo, custom hook rất phù hợp để chứa business logic. Ví dụ như xử lý phân quyền, validate form, mapping dữ liệu từ API hoặc chuẩn hoá data trước khi hiển thị.
Lúc này, hook đóng vai trò như một lớp trung gian giữa dữ liệu và UI. Component chỉ nhận kết quả cuối cùng, không cần biết chi tiết xử lý bên trong.
Cách làm này giúp:
- Logic được tái sử dụng mà không phụ thuộc giao diện
- UI component trở nên mỏng và dễ đọc hơn
- Việc test logic trở nên đơn giản hơn
Quan trọng hơn, khi UI thay đổi, business logic gần như không cần đụng tới.
3. Không nên dùng custom hook chỉ để “cho gọn component”
Một sai lầm rất phổ biến là tách custom hook chỉ vì component quá dài. Trong trường hợp này, hook thường không mang ý nghĩa nghiệp vụ rõ ràng, mà chỉ là gom vài useState và useEffect lại với nhau.
Hệ quả là:
- Hook có tên chung chung, khó hiểu
- Phải mở qua nhiều file mới hiểu được logic
- Debug mất thời gian hơn vì luồng code bị chia nhỏ
Nếu logic chỉ dùng đúng một lần và không có khả năng tái sử dụng, việc tách hook không mang lại nhiều giá trị. Khi đó, giữ logic trong component có thể còn dễ đọc hơn.
4. Không nên dùng custom hook khi logic phụ thuộc chặt vào UI
Custom hook không nên biết về UI cụ thể. Nếu hook phải nhận ref DOM, className, hoặc phụ thuộc trực tiếp vào layout, đó là dấu hiệu tách sai.
Trong những trường hợp như animation, focus input, hoặc đo kích thước element, việc dùng hook vẫn có thể chấp nhận. Tuy nhiên, hook lúc này chỉ nên đóng vai trò hỗ trợ kỹ thuật, không nên chứa nghiệp vụ.
Nếu hook bắt đầu xử lý cả UI lẫn logic, ranh giới giữa hai phần sẽ mờ đi, khiến việc maintain trở nên khó khăn.
5. Dấu hiệu cho thấy bạn nên tách custom hook
Để quyết định chính xác hơn, bạn có thể tự hỏi một vài câu sau:
- Logic này có được dùng ở nhiều component khác nhau không?
- Logic này có thể test độc lập mà không cần render UI không?
- Tên hook có thể mô tả rõ hành vi nghiệp vụ không?
- Component có trở nên dễ đọc hơn sau khi tách hook không?
Nếu phần lớn câu trả lời là “có”, thì custom hook là lựa chọn hợp lý.
6. Dấu hiệu cho thấy bạn đang lạm dụng custom hook
Ngược lại, nếu bạn gặp các tình huống sau, rất có thể custom hook đang bị dùng sai:
- Mỗi component có một hook riêng chỉ dùng đúng một lần
- Hook chỉ đơn giản là wrap
useStatemà không thêm giá trị gì - Tên hook không nói lên được logic bên trong
- Người khác phải đọc cả hook lẫn component mới hiểu được flow
Những dấu hiệu này cho thấy hook đang làm code phức tạp hơn, thay vì đơn giản hoá.
Kết luận
Custom hook không phải là công cụ để làm code “trông chuyên nghiệp hơn”. Nó là công cụ để tách logic đúng chỗ, đúng thời điểm.
Nếu dùng đúng, custom hook giúp code dễ đọc, dễ test và dễ mở rộng. Ngược lại, nếu lạm dụng, hook trở thành một lớp trừu tượng thừa, khiến người đọc mệt mỏi.
Front-end tốt không phải là nơi có nhiều hook nhất, mà là nơi mỗi hook tồn tại đều có lý do rõ ràng.
