Безопасная компиляция
Больше не нужно боятся ProviderNotFoundException
и думать об обработке состояния загрузки. С Riverpod, если ваш код компилируется, значит он работает.
Провайдер без ограничений
Riverpod вдохновлен Provider и решает его главные проблемы, такие как поддержка нескольких провайдеров одного типа, ожидание асинхронных провайдеров, создание провайдеров где-угодно, ...
Не зависит от Flutter
Создавайте / используйте / тестируйте провайдеры, не нуждаясь в Flutter. Вы можете наблюдать за провайдерами без BuildContext
.
Объявление общего состояния где-угодно
Больше не нужно переключаться между main.dart
и UI файлами.
Пишите код состояния там, где он нужен — будь то отдельный пакет или виджет — без уменьшения тестируемости.
// A shared state that can be accessed by multiple
// objects at the same time
final countProvider = StateProvider((ref) => 0);
// Consumes the shared state and rebuild when it changes
class Title extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countProvider);
return Text('$count');
}
}
Перевычисление значений / перестройка UI, только когда это необходимо
Больше не нужно осуществлять сортировку / фильтрацию внутри метода build
и использовать сложные механизмы кэширования.
С Provider
и {family} вы можете сортировать списки или выполнять HTTP запросы, только когда это действительно вам нужно.
final todosProvider = StateProvider<List<Todo>>((ref) => []);
final filterProvider = StateProvider<Filter>((ref) => Filter.all);
final filteredTodosProvider = Provider<List<Todo>>((ref) {
final todos = ref.watch(todosProvider);
switch (ref.watch(filterProvider)) {
case Filter.all:
return todos;
case Filter.completed:
return todos.where((todo) => todo.completed).toList();
case Filter.uncompleted:
return todos.where((todo) => !todo.completed).toList();
}
});
Безопасное чтение провайдеров
Чтение провайдера никогда не приведет к bad state. При правильном использовании провайдера вы всегда сможете получить допустимое значение.
Это также относится к асинхронно полученным значениям. Riverpod в отличие от provider позволяет элегантно обрабатывать загрузку/ошибки.
final configurationsProvider = FutureProvider<Configuration>((ref) async {
final uri = Uri.parse('configs.json');
final rawJson = await File.fromUri(uri).readAsString();
return Configuration.fromJson(json.decode(rawJson));
});
class Example extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final configs = ref.watch(configurationsProvider);
// Use Riverpod's built-in support
// for error/loading states using "when":
return configs.when(
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error $err'),
data: (configs) => Text('data: ${configs.host}'),
);
}
}
Проверка вашего состояния в devtool
Riverpod делает видимым ваше состояние в Flutter devtool.
Более того, уже разрабатывается полномасштабный инспектор состояния.
