Zasady projektowe stojące za miniriverpod.
Pakiet celowo zawęża możliwości, aby zachowanie było jawne: tożsamość providera na podstawie args, wstrzykiwanie w zasięgu i przewidywalna semantyka usuwania.
Co zmienia się względem Riverpod
Zamiast generowanych klas family i ukrytych kanałów notifierów, miniriverpod preferuje subclass + args + jawne invoke.
Tożsamość providera
runtimeType + hash args
Alternatywa dla family
Dziedzicz po Provider / AsyncProvider i przekaż super.args((...))
Zapas DI
Scope<T>.required + overrideWithValue
Dlaczego to ma znaczenie
O równości i override'ach można rozumować na podstawie zwykłych konstruktorów Dart, co upraszcza debugowanie i testy.
Tożsamość providera z args
args definiuje klucz providera, więc takie same args oznaczają ten sam wpis pamięci podręcznej wewnątrz ProviderContainer.
Reguła tożsamości
Praktyczne konsekwencje
- Nie jest wymagany osobny typ family.
- Nadpisanie dla każdego argumentu odbywa się przez tworzenie instancji providera.
- Utrzymuj args stabilne i niemutowalne, aby cache był przewidywalny.
Przykład: provider podobny do family + zapas Scope
Użyj argumentu konstruktora jako tożsamości i wstrzyknij instancję zapasową przez 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);
}
}
// Wstaw
ProviderScope(
overrides: [
ProductProvider.fallback.overrideWithValue(ProductProvider(search: 'jeans')),
],
child: const App(),
);
Następne kroki
Providery i odczyty
Zobacz konkretne wzorce dla watch/read/listen oraz AsyncProvider.future.
Otwórz provideryMutacje
Zaimplementuj aktualizacje stanu za pomocą mutation tokens, mutate i ref.invoke.
Otwórz mutacje