StateNotifierProvider 只改变一次
StateNotifierProvider only wach changes once
在我关于 的最后一个问题中,我计算两个 TextFormField
的问题已经解决,现在我不再使用 HookWidget
,而是尝试使用 ConsumerWidget
来实现它。我将我最后的代码迁移到:
class CalculateTextFormField extends ConsumerWidget {
@override
Widget build(BuildContext context,ScopedReader watch) {
final cashCounterProvider = watch(cashProvider);
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) =>
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),
)
],
),
),
);
}
}
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);
}
我在这里定义了 cashCounterProvider
,当我尝试将值输入 TextFormField
时,我无法输入多个值,此行为
Text('${cashCounterProvider.count + cashCounterProvider.cash}'),
确实有效一次。我尝试在输入中多次输入值时实现一个简单的计算器
除非使用 hooks,否则 Flutter 中的控制器需要在构建方法之外声明。每当您在其中一个 TextFields 中键入内容时,就会重建小部件,这会导致您的控制器被重新分配。
如果使用钩子,以下是没问题的:
class CalculatableTextFormField extends HookWidget {
@override
Widget build(BuildContext context) {
final cashCounterProvider = useProvider(cashProvider);
final TextEditingController _count = useTextEditingController();
final TextEditingController _cash = useTextEditingController();
...
否则,在构建方法之外声明控制器:
class CalculatableTextFormField extends ConsumerWidget {
final TextEditingController _count = TextEditingController();
final TextEditingController _cash = TextEditingController();
@override
Widget build(BuildContext context, ScopedReader watch) {
final cashCounterProvider = watch(cashProvider);
...
我最喜欢的钩子好处之一是不必自己处理处理逻辑。 Here is an example of handling the lifecycle of a TextEditingController. After reading that, take a look at the implementation 对于 useTextEditingController
。这应该有助于理解事情是如何运作的。
在我关于 TextFormField
的问题已经解决,现在我不再使用 HookWidget
,而是尝试使用 ConsumerWidget
来实现它。我将我最后的代码迁移到:
class CalculateTextFormField extends ConsumerWidget {
@override
Widget build(BuildContext context,ScopedReader watch) {
final cashCounterProvider = watch(cashProvider);
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) =>
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),
)
],
),
),
);
}
}
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);
}
我在这里定义了 cashCounterProvider
,当我尝试将值输入 TextFormField
时,我无法输入多个值,此行为
Text('${cashCounterProvider.count + cashCounterProvider.cash}'),
确实有效一次。我尝试在输入中多次输入值时实现一个简单的计算器
除非使用 hooks,否则 Flutter 中的控制器需要在构建方法之外声明。每当您在其中一个 TextFields 中键入内容时,就会重建小部件,这会导致您的控制器被重新分配。
如果使用钩子,以下是没问题的:
class CalculatableTextFormField extends HookWidget {
@override
Widget build(BuildContext context) {
final cashCounterProvider = useProvider(cashProvider);
final TextEditingController _count = useTextEditingController();
final TextEditingController _cash = useTextEditingController();
...
否则,在构建方法之外声明控制器:
class CalculatableTextFormField extends ConsumerWidget {
final TextEditingController _count = TextEditingController();
final TextEditingController _cash = TextEditingController();
@override
Widget build(BuildContext context, ScopedReader watch) {
final cashCounterProvider = watch(cashProvider);
...
我最喜欢的钩子好处之一是不必自己处理处理逻辑。 Here is an example of handling the lifecycle of a TextEditingController. After reading that, take a look at the implementation 对于 useTextEditingController
。这应该有助于理解事情是如何运作的。