Riverpod: Notifier
Fa parte della sezione Gestione dello stato del percorso Flutter di Coddy. Lezione 19 di 27.
Un StateProvider va bene per un numero. Quando lo stato è accompagnato da regole, come un elenco con metodi per aggiungere e rimuovere elementi, scrivi un Notifier: una classe che contiene lo stato e i metodi che lo modificano.
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 restituisce lo stato iniziale, un elenco vuoto. All'interno della classe, state è il valore corrente. GuestList.new è il costruttore della classe, passato al provider affinché possa creare il notifier.
La regola fondamentale: assegna a state un nuovo valore, non modificare mai quello vecchio. Riverpod avvisa i widget solo quando a state viene assegnato un oggetto diverso. state.add(name) modifica l'elenco sul posto, quindi state è ancora lo stesso elenco e nessuno ne viene informato. [...state, name] crea un nuovo elenco: i tre puntini ne copiano tutti i vecchi nomi, poi quello nuovo viene aggiunto alla fine.
Un widget chiama un metodo tramite il notifier: ref.read(guestsProvider.notifier).add('Ada'). Questa pagina è un ConsumerStatefulWidget, il tipo con stato, perché mantiene anche un controller di testo. Il suo State ha ref come campo.
Sfida
DifficileLa lista degli invitati mostra i nomi in guestsProvider, ma Add si limita a svuotare il campo.
- Aggiungi a
GuestListun metodoadd(String name)che impostistatesu una nuova lista con il nome in fondo. - Fai in modo che
Addlo chiami con il testo del campo, prima di svuotare il campo.
Provalo tu
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)),
],
),
),
],
),
);
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Gestione dello stato
Esercitati da solo: Compilatore Flutter online