Flutter Riverpod - 在构建方法中使用 read()
Flutter Riverpod - using read() inside build method
假设我想通过在 TextFormField
上使用 initialValue:
属性 来初始化一个文本字段,并且我需要我的初始值来自提供商。我在 docs 上读到,从构建方法内部调用 read()
被认为是不好的做法,但是从处理程序调用是好的(比如 onPressed
)。所以我想知道从 initialValue
属性 调用读取是否合适,如下所示?
不,如果您正在使用钩子,则应使用 useProvider
,否则应使用 ConsumerWidget
/ Consumer
。
不同之处在于,initialValue
字段是构建方法的一部分,正如您所说,onPressed
是构建方法之外的处理程序。
提供者的一个核心方面是在提供的值发生变化时优化重建。在构建方法中使用 context.read
会抵消此优势,因为您没有收听提供的值。
强烈建议在匿名函数(onChanged
、onPressed
、onTap
等)中使用 context.read
,因为这些函数正在检索提供的值 在函数执行时。 这意味着函数将始终使用该提供者的当前值执行,而无需监听提供者。读取提供者的其他方法使用监听器,在匿名函数的情况下,它更昂贵且不必要。
在您的示例中,您想要设置 TextFormField
的 initialValue
。以下是如何使用 hooks_riverpod and flutter_hooks 来完成此操作。
class HooksExample extends HookWidget {
const HooksExample({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextFormField(
initialValue: useProvider(loginStateProv).email,
);
}
}
对于不喜欢使用钩子的读者:
class ConsumerWidgetExample extends ConsumerWidget {
const ConsumerWidgetExample({Key key}) : super(key: key);
@override
Widget build(BuildContext context, ScopedReader watch) {
return TextFormField(
initialValue: watch(loginStateProv).email,
);
}
}
或者:
class ConsumerExample extends StatelessWidget {
const ConsumerExample({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer(
builder: (context, watch, child) {
return TextFormField(
initialValue: watch(loginStateProv).email,
);
},
);
}
}
主要区别在于 Consumer
只会重建其子项,因为只有它们依赖于提供的数据。
假设我想通过在 TextFormField
上使用 initialValue:
属性 来初始化一个文本字段,并且我需要我的初始值来自提供商。我在 docs 上读到,从构建方法内部调用 read()
被认为是不好的做法,但是从处理程序调用是好的(比如 onPressed
)。所以我想知道从 initialValue
属性 调用读取是否合适,如下所示?
不,如果您正在使用钩子,则应使用 useProvider
,否则应使用 ConsumerWidget
/ Consumer
。
不同之处在于,initialValue
字段是构建方法的一部分,正如您所说,onPressed
是构建方法之外的处理程序。
提供者的一个核心方面是在提供的值发生变化时优化重建。在构建方法中使用 context.read
会抵消此优势,因为您没有收听提供的值。
强烈建议在匿名函数(onChanged
、onPressed
、onTap
等)中使用 context.read
,因为这些函数正在检索提供的值 在函数执行时。 这意味着函数将始终使用该提供者的当前值执行,而无需监听提供者。读取提供者的其他方法使用监听器,在匿名函数的情况下,它更昂贵且不必要。
在您的示例中,您想要设置 TextFormField
的 initialValue
。以下是如何使用 hooks_riverpod and flutter_hooks 来完成此操作。
class HooksExample extends HookWidget {
const HooksExample({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextFormField(
initialValue: useProvider(loginStateProv).email,
);
}
}
对于不喜欢使用钩子的读者:
class ConsumerWidgetExample extends ConsumerWidget {
const ConsumerWidgetExample({Key key}) : super(key: key);
@override
Widget build(BuildContext context, ScopedReader watch) {
return TextFormField(
initialValue: watch(loginStateProv).email,
);
}
}
或者:
class ConsumerExample extends StatelessWidget {
const ConsumerExample({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer(
builder: (context, watch, child) {
return TextFormField(
initialValue: watch(loginStateProv).email,
);
},
);
}
}
主要区别在于 Consumer
只会重建其子项,因为只有它们依赖于提供的数据。