Provider: Consumer
Parte da seção Gerenciamento de estado do Journey de Flutter da Coddy. Lição 12 de 27.
Aqui, o provider é criado dentro do próprio build de MyApp, e o mesmo build solicita a lâmpada logo abaixo. O app exibe um erro: context pertence a MyApp, que fica acima do provider, e um widget só consegue encontrar providers que estejam acima dele.
Um Consumer resolve isso. Ele é um widget, então fica abaixo do provider, e seu builder recebe um context novo e o próprio modelo:
Consumer<Lamp>(
builder: (context, lamp, child) {
return Text(lamp.isOn ? 'On' : 'Off');
},
)O builder é executado novamente toda vez que a lâmpada chama notifyListeners(), como um widget que a observa. Dentro dele, você pode chamar os métodos do modelo diretamente em lamp: onPressed: () => lamp.toggle().
Um Consumer também reconstrói apenas o conteúdo que envolve, então envolver a parte que muda mantém o restante da tela estático. Na maioria dos apps, você usará context.watch em um widget próprio e recorrerá a Consumer quando estiver no mesmo build que o provider.
Desafio
MédioO app abre com um erro. Coloque as partes da lâmpada dentro de um Consumer:
- Envolva a
Columnem umConsumer<Lamp>e retorne aColumndo builder. - Dentro dele, use o
lampdo builder para o ícone, o texto e o botão.
Experimente você mesmo
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Lamp extends ChangeNotifier {
bool _isOn = false;
bool get isOn => _isOn;
void toggle() {
_isOn = !_isOn;
notifyListeners();
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => Lamp(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: const Text('Lamp')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
context.watch<Lamp>().isOn ? Icons.lightbulb : Icons.lightbulb_outline,
size: 96,
color: context.watch<Lamp>().isOn ? Colors.amber : Colors.grey,
),
Text(context.watch<Lamp>().isOn ? 'The lamp is on' : 'The lamp is off'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => context.read<Lamp>().toggle(),
child: const Text('Switch'),
),
],
),
),
),
),
);
}
}
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