如何解决StateNotifierProvider 不使用 HookWidget
我正在尝试使用 Riverpod
状态管理。我有两个 TextFormField
,我想通过使用 Text
取每个字段中输入的值的总和来设置 StateNotifierProvider
的值。
在以下代码中,CashCounterData
是由 StateNotifier
、CashCounter
使用的数据模型。通知程序有两个方法,setCount
和 setCash
,它们在每个 onChanged
的 TextFormField
方法中调用。
final cashProvider = StateNotifierProvider<CashCounter,CashCounterData>((ref) => CashCounter());
class CashCounter extends StateNotifier<CashCounterData> {
CashCounter() : super(_initialData);
static const _initialData = CashCounterData(0,0);
void setCount(int value){
state = CashCounterData(value,state.cash);
}
void setCash(value){
state = CashCounterData(state.count,value);
}
int get count => state.count;
int get cash => state.cash;
}
class CashCounterData {
final int count;
final int cash;
const CashCounterData(this.count,this.cash);
}
接下来,我实现了用户界面,并尝试结合上面定义的 StateNotifierProvider
。但是,当我在每个 TextFormField
中输入值时,Text
小部件始终显示 0
。
class CalculatableTextFormField extends HookWidget {
@override
Widget build(BuildContext context) {
final cashCounterProvider = useProvider(cashProvider.notifier);
final TextEditingController _count = TextEditingController();
final TextEditingController _cash = TextEditingController();
return Scaffold(
body: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: [
Text(
'${cashCounterProvider.count + cashCounterProvider.cash}'
),TextFormField(
controller: _count,keyboardType: TextInputType.number,onChanged: (value)=>cashCounterProvider.setCount(int.parse(value)),),TextFormField(
controller: _cash,onChanged: (value)=>cashCounterProvider.setCash(int.parse(value)),)
],);
}
}
我缺少什么才能获得所需的行为?
解决方法
您正在查看通知程序,而不是状态。状态会发生变化,因此会通知侦听器。
如果你只是改变它应该可以工作:
final cashCounterProvider = useProvider(cashProvider.notifier);
到:
final cashCounterProvider = useProvider(cashProvider);
然后,在您的更改处理程序中:
onChanged: (value) => context.read(cashProvider.notifier).setCash(int.tryParse(value) ?? 0),
在这样的处理程序中使用提供程序时,更喜欢上面演示的 context.read
而非 avoid unnecessary rebuilds。
如果您将 TextEditingControllers 放在 build 方法中,您还需要使用钩子。
final TextEditingController _count = useTextEditingController();
final TextEditingController _cash = useTextEditingController();
总的来说,您的解决方案如下:
class CalculatableTextFormField extends HookWidget {
@override
Widget build(BuildContext context) {
final cashCounterProvider = useProvider(cashProvider);
final TextEditingController _count = useTextEditingController();
final TextEditingController _cash = useTextEditingController();
return Scaffold(
body: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: [
Text('${cashCounterProvider.count + cashCounterProvider.cash}'),TextFormField(
controller: _count,keyboardType: TextInputType.number,onChanged: (value) =>
context.read(cashProvider.notifier).setCount(int.tryParse(value) ?? 0),),TextFormField(
controller: _cash,onChanged: (value) =>
context.read(cashProvider.notifier).setCash(int.tryParse(value) ?? 0),)
],);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。