Snapstate: Tách biệt logic nghiệp vụ khỏi React với trình quản lý trạng thái dựa trên Class

08 tháng 4, 2026·4 phút đọc

Snapstate là một thư viện mới giúp các nhà phát triển chuyển logic nghiệp vụ từ các hook React sang các class TypeScript thuần túy. Điều này giúp việc kiểm thử trở nên đơn giản hơn, giảm sự phức tạp của component và tạo ra ranh giới rõ ràng giữa giao diện và logic ứng dụng.

React được biết đến là một thư viện tuyệt vời để xây dựng giao diện người dùng (UI). Tuy nhiên, khi ứng dụng mở rộng, việc đặt toàn bộ logic của ứng dụng vào React thường dẫn đến những cấu trúc mã nguồn khó bảo trì.

Theo thời gian, nhiều codebase React thường rơi vào một mô hình chung: lấy dữ liệu trong useEffect, các quy tắc nghiệp vụ nằm trong custom hooks, giá trị phái sinh rải rác trong useMemo, và các thay đổi trạng thái ẩn trong event handlers. Mặc dù ứng dụng vẫn hoạt động, nhưng ranh giới trở nên mờ nhạt. Logic lẽ ra nên dễ kiểm thử hoặc tái sử dụng lại bị gắn chặt vào thời điểm render, quy tắc hook và vòng đời của component.

Snapstate ra đời như một giải pháp để giải quyết vấn đề này, nhằm tạo ra một ranh giới sạch sẽ hơn: React dành cho việc hiển thị, còn các class TypeScript thuần túy dành cho trạng thái và logic nghiệp vụ.

Tại sao không sử dụng các giải pháp hiện có?

Tác giả của Snapstate không xây dựng thư viện này vì thiếu các lựa chọn thay thế, mà vì muốn một sự đánh đổi khác nhau so với các công cụ phổ biến:

  • Redux: Cung cấp mô hình dự đoán được nhưng lại mang lại nhiều thủ tục (ceremony) không cần thiết đối với một số loại ứng dụng. Logic nghiệp vụ thường bị phân tán qua reducers, thunks, middleware và selectors.
  • Zustand: Nhẹ hơn rất nhiều, và dễ hiểu tại sao mọi người thích nó. Tuy nhiên, đối với các luồng xử lý lớn hơn, tác giả muốn một giải pháp ít tập trung vào hooks hơn. Khi các thao tác bất đồng bộ, giá trị phái sinh và phụ thuộc chéo giữa các stores bắt đầu tích tụ, logic vẫn cần được đọc như mã ứng dụng thông thường.
  • MobX: Có lẽ là lựa chọn gần nhất với những gì tác giả mong muốn. Nó chấp nhận sử dụng class và giữ nhiều logic ra khỏi component. Tuy nhiên, tác giả muốn một cái gì đó rõ ràng và ít "ma thuật" hơn so với việc theo dõi proxy ngầm định.

Snapstate nằm ở điểm cân bằng: các store dựa trên class, các cập nhật rõ ràng (explicit), và React đóng vai trò là bộ chuyển đổi (adapter) thay vì nơi chứa logic nghiệp vụ.

Cấu trúc mới với Snapstate

Thay vì một component Dashboard phải lo liệu việc xác thực, lấy dữ liệu, quản lý trạng thái tải/lỗi và tính toán giá trị phái sinh, Snapstate cho phép di chuyển hành vi đó vào một store.

Ví dụ, một DashboardStore sẽ chịu trách nhiệm lấy dữ liệu người dùng, tính toán số lượng thông báo chưa đọc và xử lý việc đánh dấu đã đọc. Component React (DashboardView) lúc này trở nên "ngu ngốc" hơn (dumb component), chỉ nhận các props và callbacks, không cần biết dữ liệu đến từ đâu hay cách xác thực hoạt động.

Lợi ích lớn nhất: Đơn giản hóa việc kiểm thử (Testing)

Khi logic nằm trong một class thuần túy, việc kiểm thử trở nên trực tiếp và đơn giản hơn nhiều. Bạn có thể kiểm tra logic nghiệp vụ mà không cần khởi tạo môi trường render, không cần các provider, không cần act() hay chờ đợi trạng thái UI chỉ để xác nhận một quy tắc nghiệp vụ.

Ví dụ, để kiểm tra việc đánh dấu thông báo đã đọc, bạn chỉ cần khởi tạo instance của DashboardStore, thiết lập trạng thái ban đầu và gọi phương thức markAsRead. Điều này giúp hành vi không còn bị mắc kẹt bên trong component.

Kết luận

Snapstate hiện đã có sẵn trên GitHub và npm dưới dạng mã nguồn mở. Mặc dù tác giả vẫn coi đây là phiên bản alpha để hoàn thiện các chi tiết, nhưng API cốt lõi đã ổn định và được sử dụng trong môi trường sản xuất.

Nếu bạn đang tìm kiếm một ranh giới rõ ràng giữa UI và logic trong dự án React của mình, Snapstate là một công cụ đáng để cân nhắc.

Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗