Riverpod: Notifier
Parte da seção Gerenciamento de estado do Journey de Flutter da Coddy. Lição 19 de 27.
Um StateProvider é suficiente para um número. Quando o estado vem acompanhado de regras, como uma lista com métodos para adicionar e remover itens, escreva um Notifier: uma classe que mantém o estado e os métodos que o alteram.
class GuestList extends Notifier<List<String>> {
@override
List<String> build() => [];
void add(String name) {
state = [...state, name];
}
}
final guestsProvider =
NotifierProvider<GuestList, List<String>>(GuestList.new);build retorna o estado inicial, uma lista vazia. Dentro da classe, state é o valor atual. GuestList.new é o construtor da classe, passado ao provider para que ele possa criar o notifier.
A regra principal: atribua um novo valor a state, nunca altere o antigo. O Riverpod só notifica os widgets quando state recebe um objeto diferente. state.add(name) altera a lista no próprio lugar, então state continua sendo a mesma lista e ninguém fica sabendo. [...state, name] cria uma nova lista: os três pontos espalham nela todos os nomes antigos, e o novo fica no final.
Um widget chama um método por meio do notifier: ref.read(guestsProvider.notifier).add('Ada'). Esta página é um ConsumerStatefulWidget, o tipo com estado, porque também mantém um controlador de texto. Seu State tem ref como campo.
Desafio
DifícilA lista de convidados mostra os nomes em guestsProvider, mas Add apenas limpa o campo.
- Adicione um método
add(String name)aGuestListque definastatecomo uma nova lista com o nome no final. - Faça
Addchamá-lo com o texto do campo antes de limpar o campo.
Experimente você mesmo
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class GuestList extends Notifier<List<String>> {
@override
List<String> build() => [];
}
final guestsProvider = NotifierProvider<GuestList, List<String>>(GuestList.new);
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: PartyPage(),
);
}
}
class PartyPage extends ConsumerStatefulWidget {
const PartyPage({super.key});
@override
ConsumerState<PartyPage> createState() => _PartyPageState();
}
class _PartyPageState extends ConsumerState<PartyPage> {
final controller = TextEditingController();
@override
Widget build(BuildContext context) {
final guests = ref.watch(guestsProvider);
return Scaffold(
appBar: AppBar(title: Text('Guests: ${guests.length}')),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Expanded(
child: TextField(
controller: controller,
decoration: const InputDecoration(labelText: 'Guest name'),
),
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: () {
controller.clear();
},
child: const Text('Add'),
),
],
),
),
Expanded(
child: ListView(
children: [
for (final name in guests) ListTile(leading: const Icon(Icons.person), title: Text(name)),
],
),
),
],
),
);
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Gerenciamento de estado
Pratique por conta própria: Compilador de Flutter online