Tách component theo UI hay theo business logic?

4 min read

Khi dự án còn nhỏ, cách tách component thường không quá quan trọng. Tuy nhiên, khi codebase lớn dần, quyết định này bắt đầu ảnh hưởng trực tiếp đến khả năng maintain, refactor và mở rộng tính năng. Thực tế cho thấy, rất nhiều dự án FE “toang” không phải vì code sai, mà vì cấu trúc component sai ngay từ đầu.

Vấn đề không nằm ở việc bạn dùng React, Vue hay framework nào, mà nằm ở cách bạn nhìn nhận vai trò của component trong hệ thống.

1. Tách theo UI: dễ bắt đầu nhưng dễ gãy

Cách phổ biến nhất là tách component theo UI. Nghĩa là, mỗi phần nhìn thấy trên màn hình sẽ là một component riêng: Button, Modal, Table, Card…

Ở giai đoạn đầu, cách này mang lại cảm giác rất “đã tay” khi code. Component nhỏ, dễ viết, dễ tái sử dụng. Hơn nữa, designer đổi UI thì chỉ cần sửa đúng component đó.

Tuy nhiên, vấn đề bắt đầu xuất hiện khi logic nghiệp vụ tăng lên. Lúc này, một UI component không còn đơn thuần chỉ hiển thị nữa, mà bắt đầu xử lý state, gọi API, validate dữ liệu và xử lý edge case.

Hệ quả thường thấy là:

  • Component UI ngày càng phình to
  • Logic bị lặp lại ở nhiều nơi
  • Khó test vì UI và logic dính chặt vào nhau

Nói cách khác, tách theo UI chỉ thực sự ổn khi component không mang nghiệp vụ.

2. Tách theo business logic: khó hơn nhưng bền hơn

Ngược lại, tách component theo business logic là cách tiếp cận lấy nghiệp vụ làm trung tâm. Thay vì hỏi “UI này trông như thế nào”, bạn đặt câu hỏi “nghiệp vụ này đang làm gì”.

Ví dụ, thay vì có một UserTable đơn thuần, bạn sẽ có:

  • UserList (xử lý logic lấy danh sách user, filter, pagination)
  • UserRow (chỉ hiển thị một dòng user)
  • UserActions (xử lý các hành động như edit, delete)

Theo cách này, UI component chỉ nhận data và callback, còn toàn bộ logic nằm ở component nghiệp vụ hoặc custom hook.

Ban đầu, cách làm này có vẻ rườm rà. Tuy nhiên, càng về sau, lợi ích càng rõ:

  • Logic tập trung, không bị rải rác
  • Dễ test logic mà không phụ thuộc UI
  • Dễ thay đổi UI mà không đụng tới nghiệp vụ

Quan trọng hơn, business logic thường thay đổi ít hơn UI, nên việc tách như vậy giúp hệ thống ổn định lâu dài.

3. Sai lầm phổ biến: nhầm lẫn giữa UI component và business component

Một lỗi rất hay gặp là gọi mọi component là “component”, nhưng lại không phân biệt vai trò của chúng. Điều này dẫn đến việc UI component ôm luôn logic, trong khi business component lại đi render UI chi tiết.

Để tránh sai lầm này, bạn nên phân biệt rõ:

  • UI component: không gọi API, không xử lý nghiệp vụ, chỉ render
  • Business component: quản lý state, xử lý logic, kết nối dữ liệu

Khi ranh giới này rõ ràng, việc refactor hoặc mở rộng tính năng sẽ nhẹ hơn rất nhiều.

4. Kết hợp cả hai, nhưng phải có thứ tự ưu tiên

Thực tế, không phải lúc nào cũng chọn một trong hai. Phần lớn dự án tốt đều kết hợp cả UI-based và business-based component. Tuy nhiên, thứ tự ưu tiên rất quan trọng.

Một hướng tiếp cận an toàn là:

  • Tách business logic trước
  • Sau đó mới tách UI component để tái sử dụng

Cách làm này giúp bạn không bị UI dẫn dắt cấu trúc hệ thống. Thay vào đó, nghiệp vụ sẽ là xương sống, còn UI chỉ là lớp hiển thị bên ngoài.

5. Dấu hiệu cho thấy bạn đang tách sai

Nếu bạn thấy mình thường xuyên gặp các tình huống sau, rất có thể cấu trúc component đang có vấn đề:

  • Component vừa render vừa xử lý quá nhiều logic
  • Cùng một nghiệp vụ nhưng code lặp ở nhiều component khác nhau
  • Sửa UI nhưng phải động vào logic bên trong
  • Viết test cho component rất khó hoặc gần như không viết được

Những dấu hiệu này không xuất hiện ngay, mà tích tụ theo thời gian. Do đó, càng phát hiện sớm, chi phí sửa càng thấp.

Kết luận

Tách component không phải là vấn đề code style, mà là vấn đề tư duy hệ thống. Tách theo UI giúp bạn đi nhanh lúc đầu, nhưng tách theo business logic giúp bạn đi xa.

Một front-end dev tốt không phải là người chia component cho “đẹp”, mà là người chia component sao cho sau này ít phải quay lại sửa nhất. Khi nghiệp vụ được đặt đúng chỗ, UI chỉ còn là phần dễ thay đổi nhất trong toàn bộ hệ thống.

Tài liệu tham khảo

React Component Architecture: Best Practices for Scale

Top React Design Patterns dominating React Development lifecycle

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *