StateNotifierProvider没有使用HookWidget更新状态



我正在尝试使用Riverpod状态管理。我有两个TextFormField,我想通过使用StateNotifierProvider在每个字段中输入的值的总和来设置Text的值。

在下面的代码中,CashCounterDataStateNotifierCashCounter使用的数据模型。通知器有两个方法,setCountsetCash,分别在每个TextFormFieldonChanged方法中调用。

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);
}

接下来,我实现了UI,并尝试在上面定义的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,
keyboardType: TextInputType.number,
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,以避免不必要的重建。

你还需要使用钩子,如果你把你的TextEditingControllers在构建方法。

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,
keyboardType: TextInputType.number,
onChanged: (value) =>
context.read(cashProvider.notifier).setCash(int.tryParse(value) ?? 0),
)
],
),
),
);
}
}

相关内容

  • 没有找到相关文章

最新更新