Menu
CoddyTech

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.

challenge icon

Défi

Difficile

La liste des invités affiche les noms dans guestsProvider, mais Add ne fait qu’effacer le champ.

  • Ajoute à GuestList une méthode add(String name) qui définit state sur une nouvelle liste avec le nom à la fin.
  • Fais en sorte que Add l’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)),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
quiz iconTestez-vous

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