Những nguyên tắc thiết kế phía sau miniriverpod.
Gói này cố ý thu hẹp tính năng để giữ cho hành vi thật rõ ràng: định danh provider bằng args, tiêm theo scope và semantics giải phóng có thể dự đoán.
Điều gì thay đổi so với Riverpod
Thay vì các family class được sinh ra và các kênh notifier ngầm định, miniriverpod ưu tiên subclass + args + invoke tường minh.
Định danh provider
runtimeType + hash của args
Phương án thay cho family
Subclass Provider / AsyncProvider và truyền super.args((...))
DI dự phòng
Scope<T>.required + overrideWithValue
Vì sao điều này quan trọng
Bạn có thể suy luận về equality và overrides từ các constructor Dart thuần, giúp debug và kiểm thử rất trực tiếp.
Định danh Provider với args
args xác định key của provider, nên args bằng nhau có nghĩa là cùng một cache entry bên trong ProviderContainer.
Quy tắc định danh
Hệ quả thực tế
- Không cần một family type riêng.
- Override theo từng đối số được thực hiện bằng cách tạo các provider instance.
- Giữ args ổn định và bất biến để caching có thể dự đoán.
Ví dụ: provider giống family + Scope dự phòng
Dùng một đối số của constructor làm định danh và tiêm một instance dự phòng qua Scope.
class ProductProvider extends AsyncProvider<List<Product>> {
ProductProvider({this.search = ''}) : super.args((search,));
final String search;
static final fallback = Scope<ProductProvider>.required('product.fallback');
@override
FutureOr<List<Product>> build(ref) async {
final api = ref.watch(productsApiProvider);
return api.search(q: search);
}
}
// Chèn
ProviderScope(
overrides: [
ProductProvider.fallback.overrideWithValue(ProductProvider(search: 'jeans')),
],
child: const App(),
);
Các bước tiếp theo
Providers và đọc dữ liệu
Xem các mẫu cụ thể cho watch/read/listen và AsyncProvider.future.
Mở Providers