英文:
Why is my Flutter Riverpod counter not updating on UI?
问题
The counter on the UI may not be updating because the UI does not automatically rebuild when the state changes. In your Flutter code, you are using Riverpod to manage state, but you also need to ensure that your UI rebuilds when the state changes.
To make sure the UI updates when the state changes, you should use the Consumer
widget to watch the state and rebuild the relevant part of your UI when the state changes. Here's an example of how you can update your MyApp
widget to use the Consumer
widget to watch the men
value and update the UI:
class MyApp extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
// Watch the 'men' value from the populationController
final men = ref.watch(populationController).men.toString();
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Example')),
body: Center(
child: Column(
children: [
Text("Amount of men is $men"),
IconButton(
onPressed: () {
ref.read(populationController.notifier).increaseMen();
},
icon: const Icon(Icons.plus_one),
),
],
),
),
),
);
}
}
With this change, the UI will update when the 'men' value in the state changes because the Consumer
widget is watching it. Make sure you have this code in place, and if the counter still doesn't update on the UI, please check for any other potential issues in your code or UI setup.
英文:
Main Flutter Counter
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'data/providers.dart';
void main() {
runApp(
// For widgets to be able to read providers, we need to wrap the entire
// application in a "ProviderScope" widget.
// This is where the state of our providers will be stored.
ProviderScope(
child: MyApp(),
),
);
}
class MyApp extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
var men = ref.watch(populationController).men.toString();
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Example')),
body: Center(
child: Column(
children: [
Text("Amount of men is $men"),
IconButton(
onPressed: () {
ref.read(populationController.notifier).increaseMen();
},
icon: const Icon(Icons.plus_one))
],
)),
),
);
}
}
File where I define riverpod class
import 'package:flutter_riverpod/flutter_riverpod.dart';
class PopulationTracker {
int women = 0;
int men = 0;
}
class PopulationNotifier extends StateNotifier<PopulationTracker> {
PopulationNotifier() : super(PopulationTracker());
void increaseMen() {
state.men += 1;
}
void increaseWomen() {
state.women += 1;
}
void minusWomen() {
state.women -= 1;
}
void minusMen() {
state.men -= 1;
}
}
final populationController =
StateNotifierProvider<PopulationNotifier, PopulationTracker>(
(ref) => PopulationNotifier());
I was trying to update the state of my population tracker using riverpod and flutter. I am pretty new to this and cannot figure out why the counter on UI does not update I can see the value update if I print the value of state to console.
I was expecting the counter to update to +1 on UI but it does not.
Why does the counter not update on UI?
答案1
得分: 1
状态对象并未改变其身份,仅发生了变异。变异并不足以向侦听器发出新事件。您需要将状态视为只读,并使用诸如 copyWith
等操作使其生效。
此外,您应该放弃使用 StateNotifier
,开始使用 Notifier
。如果您一直在使用 Notifier
,我还可以建议您仅在变异方法中添加 ref.notifyListeners()
,以使其正常工作。
总结一下,请停止使用 ChangeNotifier
、StateNotifier
和 StateProvider
。它们仅受支持于传统目的。
英文:
The state object is not changing identity. Just mutating. Mutating is not enough to emit a new event to listeners. You need to treat state as readonly and use operations like copyWith to make it work.
Also, you should move away from StateNotifier and start using Notifier. If you had been using Notifier, I could also advise you to merely add ref.notifyListeners() for your mutate methods, and get it to work that way.
In summary, please stop using ChangeNotifier, StateNotifier, and StateProvider. They are supported only for legacy purposes.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论