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(),
);
Scope utrzymuje powiązania zależności w sposób jawny i przyjazny testom.
overrideWithValue działa dla każdej instancji providera, także tych opartych na args.
Zachowanie autoDispose nie zmienia się przy użyciu subclass + args.

Następne kroki

Providery i odczyty

Zobacz konkretne wzorce dla watch/read/listen oraz AsyncProvider.future.

Otwórz providery

Mutacje

Zaimplementuj aktualizacje stanu za pomocą mutation tokens, mutate i ref.invoke.

Otwórz mutacje