Riverpod : Notifier
Fait partie de la section Gestion d’état du Journey Flutter de Coddy. Leçon 19 sur 27.
Un StateProvider convient pour un seul nombre. Lorsque l’état est soumis à des règles, par exemple une liste avec des méthodes pour ajouter et supprimer des éléments, écris un Notifier : une classe qui contient l’état et les méthodes qui le modifient.
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 renvoie le premier état, une liste vide. À l’intérieur de la classe, state est la valeur actuelle. GuestList.new est le constructeur de la classe, transmis au fournisseur afin qu’il puisse créer le notificateur.
La règle essentielle : attribue une nouvelle valeur à state, ne modifie jamais l’ancienne. Riverpod avertit les widgets uniquement lorsque state reçoit un objet différent. state.add(name) modifie la liste sur place : state reste donc la même liste et personne n’en est averti. [...state, name] crée une nouvelle liste : les trois points y déploient tous les anciens noms, puis le nouveau est ajouté à la fin.
Un widget appelle une méthode par l’intermédiaire du notificateur : ref.read(guestsProvider.notifier).add('Ada'). Cette page est un ConsumerStatefulWidget, le type avec état, car elle conserve également un contrôleur de texte. Son State possède ref comme champ.
Défi
DifficileLa liste des invités affiche les noms dans guestsProvider, mais Add ne fait qu’effacer le champ.
- Ajoute à
GuestListune méthodeadd(String name)qui définitstatesur une nouvelle liste avec le nom à la fin. - Fais en sorte que
Addl’appelle avec le texte du champ avant d’effacer celui-ci.
Essayez vous-même
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)),
],
),
),
],
),
);
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Gestion d’état
Entraînez-vous par vous-même : Compilateur Flutter en ligne