Compilação segura
Não mais ProviderNotFoundException
ou esquecendo de lidar com estados de carregamento. Usando Riverpod, se seu código compila, ele funciona.
Provider, sem suas limitações
Riverpod é inspirado no Provider, mas resolve alguns de seus principais problemas, como suporte a vários providers do mesmo tipo; aguardando providers assíncronos; adicionando providers de qualquer lugar, ...
Não depende do Flutter
Crie/compartilhe/teste providers, sem dependência do Flutter. Isso inclui poder ouvir providers sem um BuildContext
.
Declare o estado compartilhado de qualquer lugar
Não há mais necessidade de pular entre o main.dart
e seus arquivos de interface do usuário. Coloque o código do seu estado compartilhado onde ele pertence, seja em um pacote separado ou bem ao lado do Widget que precisa dele, sem perder a testabilidade.
// 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 {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countProvider);
return Text('$count');
}
}
Recompute estados, Rebuild a UI somente quando necessário
Não precisamos mais classificar/filtrar listas dentro do método build
ou recorrer ao mecanismo de cache avançado.
Com Provider
e "families", classifique suas listas ou faça solicitações HTTP somente quando você realmente precisar.
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();
}
});
Leia os providers com Segurança
Ler um provider nunca resultará em um estado ruim. Se você puder escrever o código necessário para ler um provedor, obterá um valor válido.
Isso se aplica até mesmo a valores carregados de forma assíncrona. Ao contrário do provider, o Riverpod permite lidar de forma limpa com casos de carregamento/erro.
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 {
@override
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}'),
);
}
}
Inspecione seu estado no devtool
Usando Riverpod, seu estado é visível fora da caixa dentro do devtool do Flutter.
Além disso, uma ferramenta abrangente de inspeção de estado está em desenvolvimento.
