【问题标题】:Flutter Riverpod - using read() inside build methodFlutter Riverpod - 在构建方法中使用 read()
【发布时间】:2021-01-22 22:45:34
【问题描述】:

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

【问题讨论】:

    标签: flutter flutter-provider


    【解决方案1】:

    不,如果您使用挂钩,则应使用 useProvider,否则应使用 ConsumerWidget / Consumer

    不同之处在于,initialValue 字段是构建方法的一部分,就像你说的,onPressed 是一个处理程序,在构建方法之外。

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

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

    在您的示例中,您想设置 initialValueTextFormField。以下是您如何使用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,
        );
      }
    }
    

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

    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 只会重建其子代,因为只有它们依赖于提供的数据。

    【讨论】:

    • 谢谢,有点怀疑。我很感激这些信息,所以如果我做对了,我应该做类似initialValue: useProvider(someProvider.select((value) => value.someField)), 的事情?
    • 假设我想显示someField。此外,onChanged 是否与onPressed 属于同一类别,是否在onChanged 上的onChanged 上使用read() 安全?
    • 通过扩展我的答案解决了您的问题。您似乎已删除您的帐户,但希望它仍然可以帮助您和未来的读者。
    • 谢谢@alex-hartford,很高兴我找到了这个——帮了我很多!
    • @OmarEssam read 就像它的名字一样,在您调用 read 时读取值。 watch 将在您调用 watch 时读取该值,但会继续关注所提供值的更新,并在这些更新发生时更新/重建。
    猜你喜欢
    • 2021-01-25
    • 2022-08-08
    • 2022-07-17
    • 2021-03-26
    • 2021-04-04
    • 2021-05-03
    • 2021-03-17
    • 2021-03-19
    • 1970-01-01
    相关资源
    最近更新 更多