Flutter Riverpod - 在构建方法中使用 read()

1 flutter flutter-provider

假设我想通过使用 a 上的initialValue:属性来初始化一个文本字段TextFormField,并且我需要我的初始值来自提供者。我在文档中读到read()从 build 方法内部调用被认为是不好的做法,但从处理程序调用很好(如onPressed)。所以我想知道从initialValue属性中调用 read 是否可以,如下所示?

在此处输入图片说明

Ale*_*ord 7

不,useProvider如果你正在使用钩子,你应该使用,或者如果你没有使用ConsumerWidget/ Consumer

不同之处在于,该initialValue字段是 build 方法的一部分,就像您说的那样,onPressed是 build 方法之外的处理程序。

提供者的一个核心方面是在提供的值发生变化时优化重建。context.read在 build 方法中使用会使这种好处无效,因为您没有在听提供的值。

使用context.read强烈建议在匿名函数(onChangedonPressedonTap等),因为这些功能检索所提供的值在执行该功能的时间。这意味着该函数将始终使用该提供者的当前值执行,而无需侦听该提供者。读取提供程序的其他方法使用侦听器,这在匿名函数的情况下更昂贵且不必要。

在您的示例中,您想设置initialValue一个TextFormField. 以下是如何使用hooks_riverpodflutter_hooks来实现这一点。

class HooksExample extends HookWidget {
  const HooksExample({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      initialValue: useProvider(loginStateProv).email,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

对于不喜欢使用钩子的读者:

class ConsumerWidgetExample extends ConsumerWidget {
  const ConsumerWidgetExample({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    return TextFormField(
      initialValue: watch(loginStateProv).email,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

或者:

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,
        );
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

主要区别在于它Consumer只会重建它的孩子,因为只有他们依赖提供的数据。

  • 通过扩展我的答案来解决您的问题。您似乎已经删除了帐户,但希望它仍然可以帮助您和未来的读者。 (2认同)