Skip to main content

Lỗi thường gặp

Danh sách các vi phạm convention hay gặp khi review code. Mục đích là nhận diện nhanh và tránh lặp lại; chi tiết quy tắc xem các trang TypeScript, React, Next.js và Styling.

Không comment hàm / API​

Vấn đề: Hàm public, Server Action, service quan trọng không có JSDoc hoặc comment mô tả hành vi, tham số, giá trị trả về.

Cách làm đúng: Thêm JSDoc cho function/API phức tạp; type rõ ràng thì có thể ngắn gọn. Xem Comments & Formatting và Server Actions.


Inline function trong JSX​

Vấn đề: Truyền onClick={() => ...} hoặc onChange={(e) => ...} trực tiếp trong JSX khiến tạo hàm mới mỗi lần render, dễ gây re-render không cần thiết ở component con được memo.

Cách làm đúng: Dùng useCallback khi truyền xuống component tối ưu; hoặc tách handler ra biến/hàm có tên. Xem Hooks & useEffect và Styling - UI rules.


Inline style​

Vấn đề: Dùng style={{ ... }} rải rác trong component thay vì class Tailwind/CSS module.

Cách làm đúng: Dùng class (Tailwind, CSS module), tránh inline style trừ trường hợp giá trị thực sự động (ví dụ width theo prop). Xem UI rules.


Không dùng cn (clsx + tailwind-merge)​

Vấn đề: Ghép chuỗi class hoặc template string khiến class Tailwind xung đột (cùng thuộc tính) không được merge đúng; hoặc điều kiện class dài khó đọc.

Cách làm đúng: Dùng helper cn (clsx + tailwind-merge) để gộp class có điều kiện và resolve xung đột.

// bad
<div className={`px-4 py-2 ${active ? 'bg-blue-500' : 'bg-gray-200'}`} />

// good
import { cn } from '@/lib/utils';
<div className={cn('px-4 py-2', active ? 'bg-blue-500' : 'bg-gray-200')} />

Import không đúng quy ước​

Vấn đề: Import sâu từng file thay vì barrel; import từ app/; barrel import không cần thiết gây bundle lớn; đường dẫn alias không thống nhất.

Cách làm đúng: Import qua index.ts khi team quy định; không import từ thư mục app cho shared code; dùng alias @/ thống nhất. Xem Modules.


Không có loading / skeleton​

Vấn đề: Màn hình fetch dữ liệu nhưng không hiển thị trạng thái đang tải — user thấy trống hoặc nhảy layout.

Cách làm đúng: Dùng Skeleton (hoặc spinner có chủ đích) phản ánh layout nội dung. Xem Loading & Empty State.


Không có empty state​

Vấn đề: Danh sách rỗng hoặc không có kết quả tìm kiếm nhưng không có message/CTA.

Cách làm đúng: Component Empty State rõ ràng (message + hành động nếu cần). Xem Loading & Empty State.


Không phân quyền trên Server Action / API​

Vấn đề: Chỉ ẩn nút trên UI nhưng Action không kiểm tra quyền — user có thể gọi trực tiếp và thực hiện thao tác không được phép.

Cách làm đúng: Luôn kiểm tra auth/org/role trong Action (hoặc layer tương đương) trước khi thực hiện. Xem Authorization.


Tóm tắt checklist nhanh​

Lỗi thường gặpHành động
Thiếu comment hàm/APIBổ sung JSDoc / comment
Inline function trong JSXuseCallback hoặc handler tách riêng
Inline styleClass + Tailwind / CSS module
Class Tailwind xung độtDùng cn + tailwind-merge
Import lộn xộnBarrel, alias, không import từ app
Không loadingSkeleton / trạng thái tải
Không empty stateEmpty State component
Không phân quyền backendKiểm tra trong Server Action