Принципи дизайну, що стоять за miniriverpod.
Пакет навмисно звужує функціональність, щоб поведінка залишалася явною: ідентичність провайдера через args, інʼєкція через Scope та передбачувана семантика видалення.
Що змінюється порівняно з Riverpod
Замість згенерованих family-класів і неявних каналів notifier miniriverpod надає перевагу subclass + args + explicit invoke.
Ідентичність провайдера
runtimeType + args hash
Альтернатива family
Наслідуйте Provider / AsyncProvider і передавайте super.args((...))
DI-резерв
Scope<T>.required + overrideWithValue
Чому це важливо
Ви можете міркувати про рівність і перевизначення на основі звичайних Dart-конструкторів, що робить налагодження та тести простішими.
Ідентичність провайдера з args
args визначає ключ провайдера, тож однакові args означають той самий запис кешу всередині ProviderContainer.
Правило ідентичності
Практичні наслідки
- Окремий family-тип не потрібен.
- Перевизначення для кожного аргументу виконується шляхом створення екземплярів провайдера.
- Тримайте args стабільними та незмінними для передбачуваного кешування.
Приклад: provider, схожий на family + запасний Scope
Використовуйте аргумент конструктора як ідентичність і інʼєктуйте запасний екземпляр через 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);
}
}
// Вставити
ProviderScope(
overrides: [
ProductProvider.fallback.overrideWithValue(ProductProvider(search: 'jeans')),
],
child: const App(),
);
Наступні кроки
Провайдери та читання
Перегляньте конкретні патерни для watch/read/listen і AsyncProvider.future.
Відкрити провайдериМутації
Реалізуйте оновлення стану за допомогою mutation tokens, mutate та ref.invoke.
Відкрити мутації