Ba lựa chọn phổ biến nhất, khác nhau chủ yếu ở mức ràng buộc kiến trúc:
| Provider | Riverpod | BLoC / Cubit | |
|---|---|---|---|
| Bản chất | Wrapper quanh InheritedWidget + ChangeNotifier | Viết lại từ Provider, không phụ thuộc BuildContext | Luồng event → state trên Stream |
| Lỗi thiếu provider | ProviderNotFoundException lúc runtime | Phát hiện lúc compile | Lúc runtime, nhưng cấu trúc rõ |
| Async | Tự quản loading/error | AsyncValue có sẵn loading/error/data | Tự định nghĩa state loading/error |
| Hợp với | App nhỏ–vừa, team mới làm Flutter | App vừa–lớn, nhiều async, cần test và cache | Team lớn, nghiệp vụ phức tạp, cần truy vết mọi thay đổi |
Mốc cần biết: Riverpod 3.0 (2025) gộp các loại Ref thành một, tự động retry khi provider lỗi, thêm (thử nghiệm) offline persistence và mutations. Provider và Riverpod cùng tác giả (Remi Rousselet); ví dụ cơ bản trên docs Flutter vẫn dùng ChangeNotifier + Provider.
Khi phỏng vấn, nên trả lời theo tiêu chí: quy mô team, độ phức tạp nghiệp vụ, nhu cầu test, và thứ team đã quen. Ví dụ: app ngân hàng nhiều luồng nghiệp vụ, nhiều người cùng code → BLoC để mọi thay đổi state đi qua event, dễ log và test; app nội bộ gọi API nhiều, cần cache → Riverpod.
Lưu ý: trộn nhiều giải pháp trong một app (vừa Provider vừa BLoC vừa GetX) là điểm trừ khi review code. Chọn một hướng chính và giữ nhất quán.