Menu
CoddyTech

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.

challenge icon

Desafio

Difícil

A lista de convidados mostra os nomes em guestsProvider, mas Add apenas limpa o campo.

  • Adicione um método add(String name) a GuestList que defina state como uma nova lista com o nome no final.
  • Faça Add chamá-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)),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
quiz iconTeste seus conhecimentos

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