miniriverpod-ის უკან მდგარი დიზაინის პრინციპები.
პაკეტი განზრახ ზღუდავს ფუნქციებს, რათა ქცევა მკაფიო დარჩეს: provider-ის იდენტობა args-ით, Scope-ის მეშვეობით scope-ირებული ინექცია და პროგნოზირებადი განტვირთვის სემანტიკა.
რა იცვლება Riverpod-თან შედარებით
გენერირებული family კლასებისა და იმპლიციტური notifier არხების ნაცვლად, miniriverpod-ი ანიჭებს უპირატესობას subclass + args + explicit invoke მიდგომას.
Provider-ის იდენტობა
runtimeType + args hash
family-ის ალტერნატივა
გააფართოვეთ Provider / AsyncProvider როგორც subclass და გადასვით super.args((...))
DI-ის სარეზერვო ვარიანტი
Scope<T>.required + overrideWithValue
რატომ არის ეს მნიშვნელოვანი
ეკვივალენტობაზე და override-ებზე შეგიძლიათ მსჯელობა ჩვეულებრივი Dart კონსტრუქტორებიდან, რაც debugging-სა და tests-ს მარტივს ტოვებს.
Provider-ის იდენტობა args-ით
args განსაზღვრავს provider-ის გასაღებს, ამიტომ ერთნაირი args ნიშნავს იგივე cache entry-ს ProviderContainer-ის შიგნით.
იდენტობის წესი
პრაქტიკული შედეგები
- სპეციალური family ტიპი საჭირო არ არის.
- თითო არგუმენტზე override კეთდება provider-ის instance-ების შექმნით.
- შეინარჩუნეთ args სტაბილურად და immutable-ად პროგნოზირებადი cache-ისთვის.
მაგალითი: family-ს მსგავსი provider + Scope-ის fallback
გამოიყენეთ კონსტრუქტორის არგუმენტი იდენტობად და Scope-ის მეშვეობით ჩასვით fallback instance.
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);
}
}
// ინექცია
ProviderScope(
overrides: [
ProductProvider.fallback.overrideWithValue(ProductProvider(search: 'jeans')),
],
child: const App(),
);
შემდეგი ნაბიჯები
Provider-ები და წაკითხვები
ნახეთ watch/read/listen და AsyncProvider.future-ის კონკრეტული შაბლონები.
Provider-ების გახსნაMutations
განახორციელეთ state-ის განახლება mutation token-ებით, mutate-ით და ref.invoke-ით.
Mutations-ის გახსნა