Principiile de design din spatele miniriverpod.
Pachetul restrânge intenționat funcționalitățile pentru a păstra comportamentul explicit: identitatea providerului prin args, injectare cu scope și semantica previzibilă a eliminării.
Ce se schimbă față de Riverpod
În locul claselor family generate și al canalelor implicite de notifier, miniriverpod preferă subclass + args + invoke explicit.
Identitatea providerului
runtimeType + hash args
alternativă la family
Subclasează Provider / AsyncProvider și transmite super.args((...))
fallback DI
Scope<T>.required + overrideWithValue
De ce contează asta
Poți raționa despre egalitate și override-uri pornind de la constructori Dart obișnuiți, ceea ce păstrează depanarea și testele simple.
Identitatea providerului cu args
args definește cheia providerului, astfel că args egale înseamnă aceeași intrare în cache în interiorul unui ProviderContainer.
Regula identității
Consecințe practice
- Nu este necesar un tip family dedicat.
- Suprascrierea per argument se face prin crearea de instanțe de provider.
- Păstrează args stabile și imuabile pentru o memorare în cache previzibilă.
Exemplu: provider asemănător family + fallback Scope
Folosește un argument al constructorului ca identitate și injectează o instanță de rezervă prin 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);
}
}
// Injectează
ProviderScope(
overrides: [
ProductProvider.fallback.overrideWithValue(ProductProvider(search: 'jeans')),
],
child: const App(),
);
Pașii următori
Provideri și citiri
Vezi tipare concrete pentru watch/read/listen și AsyncProvider.future.
Deschide provideriMutații
Implementează actualizări de stare cu mutation tokens, mutate și ref.invoke.
Deschide mutații