Menu
CoddyTech

Provider: osservare o leggere

Fa parte della sezione Gestione dello stato del percorso Flutter di Coddy. Lezione 11 di 27.

Ci sono due modi per ottenere un modello da Provider e svolgono funzioni diverse.

context.watch<StepCounter>() ottiene il modello e si iscrive a esso: quando il modello chiama notifyListeners(), questo widget viene ricostruito. Usalo in build, per tutto ciò che viene mostrato sullo schermo.

context.read<StepCounter>() ottiene il modello una volta, senza iscriversi. Usalo nei callback come onPressed, quando vuoi chiamare un metodo e non mostrare nulla:

Widget build(BuildContext context) {
  final steps = context.watch<StepCounter>().steps;   // mostra
  return ElevatedButton(
    onPressed: () => context.read<StepCounter>().walk(),   // agisce
    child: Text('$steps steps'),
  );
}

Se li confondi, te ne accorgi. read in build mostra per sempre il primo valore. watch all'interno di onPressed è un errore, perché un tocco non è una build e non c'è nulla a cui iscriversi.

challenge icon

Sfida

Facile

Walk aggiunge 1000 passi al modello, ma sullo schermo rimane visualizzato 0 steps.

  • Fai in modo che la riga dei passi segua il modello, così ogni tocco mostra il nuovo numero.
  • Lascia invariata la chiamata del pulsante.

Provalo tu

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class StepCounter extends ChangeNotifier {
  int _steps = 0;

  int get steps => _steps;

  void walk() {
    _steps += 1000;
    notifyListeners();
  }
}

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => StepCounter(),
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    final steps = context.read<StepCounter>().steps;
    return Scaffold(
      appBar: AppBar(title: const Text('Steps')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('$steps steps', style: const TextStyle(fontSize: 40)),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                context.read<StepCounter>().walk();
              },
              child: const Text('Walk'),
            ),
          ],
        ),
      ),
    );
  }
}
quiz iconMettiti alla prova

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