【问题标题】:When to use Provider.of<X> vs. Consumer<X> in FlutterFlutter 中何时使用 Provider.of<X> 与 Consumer<X>
【发布时间】:2020-03-05 13:02:23
【问题描述】:

我仍在纠结于状态管理技术,对于何时以及为什么使用 Provider.of&lt;X&gt;Consumer&lt;X&gt; 有点困惑。我从documentation 了解到(我认为),在这两者之间进行选择时,当我们想要访问数据时,您将使用 Provider.of,但您不需要更改 UI。因此,以下内容(取自文档)可以访问数据并根据新事件更新 UI:

return HumongousWidget(
  // ...
  child: AnotherMonstrousWidget(// <- This widget will rebuild on new data events
    // ...
    child: Consumer<CartModel>(
      builder: (context, cart, child) {
        return Text('Total price: ${cart.totalPrice}');
      },
    ),
  ),
);

然而,如果我们只需要不想使用 UI 重建的数据,我们将使用 Provider.of&lt;X&gt; 并将 listen 参数设置为 false,如下所示:

Provider.of<CartModel>(context, listen: false).add(item); \\Widget won't rebuild

但是,listen 不是必需的,因此也将运行以下命令:

Provider.of<CartModel>(context).add(item); \\listener optional

所以这给我带来了几个问题:

  1. 这是区分Provider.of&lt;X&gt;Consumer&lt;X&gt;的正确方法吗?前者不更新 UI,后者更新?
  2. 如果listen 未设置为false,小部件是默认重建还是不重建?如果listen 设置为true 会怎样?
  3. 我们有Consumer,为什么Provider.of 可以选择重建用户界面?

【问题讨论】:

    标签: flutter dart flutter-provider


    【解决方案1】:

    没关系。但是为了快速解释事情:

    Provider.of 是获取和收听对象的唯一方式。 ConsumerSelector 和所有 *ProxyProvider 调用 Provider.of 工作。

    Provider.ofConsumer 是个人喜好问题。但两者都有一些论据

    提供者.of

    • 可以在所有小部件生命周期中调用,包括点击处理程序和didChangeDependencies
    • 不增加缩进

    消费者

    • 允许更精细的小部件重建
    • 解决大多数 BuildContext 误用

    【讨论】:

    • 这很有帮助。我会接受这个回应,尤其是对其他人。但是你能不能指出这句话的引用:“Provider.of 是获取和监听对象的唯一方法。Consumer、Selector 和所有 *ProxyProvider 调用 Provider.of 才能工作。”这不是我在文档中看到的内容,它确实帮助了我!
    • 这只是 Consumer/... 如何工作的一个实现细节。这是source。你可以看到Consumer在一个新的小部件中基本上只是Provider.of
    • 有没有关于学习防止 BuildContext 误用的资源?
    • @RémiRousselet 链接不再起作用。工作链接是:source
    【解决方案2】:

    对于您的问题:

    1. 这是区分Provider.of&lt;X&gt;Consumer&lt;X&gt; 的正确方法吗?前者不更新 UI,后者更新?

    Provider.of&lt;X&gt; 取决于listen 的值来触发新的State.build 到小部件和State.didChangeDependencies 用于StatefulWidget

    Consumer&lt;X&gt; 始终更新 UI,因为它使用 Provider.of&lt;T&gt;(context),其中 listentrue。查看完整源代码here

    1. 如果listen 未设置为false,小部件是默认重建还是不重建?如果listen 设置为true 会怎样?

    默认值为true,表示将触发新的State.build 到小部件和State.didChangeDependencies 用于StatefulWidget。查看完整源代码here

    static T of&lt;T&gt;(BuildContext context, {bool listen = true}).

    1. 我们有Consumer,为什么Provider.of 可以选择重建用户界面?

    Rémi Rousselet 的 answer 几乎涵盖了所有内容。

    【讨论】:

      【解决方案3】:

      使用它不应该有任何性能问题,此外,如果我们只想在屏幕上更改某些特定的小部件,我们应该使用消费者。就编码实践而言,这是我可以说的最佳方法。

       return Container(
          // ...
          child: Consumer<PersonModel>(
            builder: (context, person, child) {
              return Text('Name: ${person.name}');
            },
          ),
        );
      

      和上面的例子一样,我们只需要更新 Single Text Widget 的值,所以在那里添加消费者而不是其他小部件也可以访问的 Provider。

      注意:消费者或提供者更新您的实例的唯一引用,哪些小部件正在使用,如果某些小部件未使用,则不会重新绘制。

      【讨论】:

        【解决方案4】:

        提供者.of

        应用提供者,如果监听为真,整个小部件将重建。

        消费者

        仅使用消费者特别允许的小部件将重建。

        【讨论】:

          【解决方案5】:

          小部件Consumer 没有做任何花哨的工作。它只是在一个新的小部件中调用Provider.of,并将其构建实现委托给[builder]。 它只是Provider.of 的语法糖,但有趣的是我认为Provider.of 更易于使用。

          查看本文了解更多信息 https://blog.codemagic.io/flutter-tutorial-provider/

          【讨论】:

            【解决方案6】:

            这里有 3 件事要理解。

            当您将 Provider 包裹在小部件周围时,它会设置对小部件树的引用和您想要引用其更改的变量。

            使用 Provider.of(context) 您可以访问要监控的变量并对其进行更改。

            Provider.of(context) with and without listen 为您提供了对上面声明的 Provider 对象的引用以及可以从中访问它的小部件树。但正如其他人所说,当 listen 不为假时,它会重建它所在的整个小部件树。

            最后,您可以使用消费者来监控使用上述步骤发生的任何更改

            消费者充当更细粒度的侦听器,并应用于固定小部件,以帮助避免不必要的重建。

            【讨论】:

              猜你喜欢
              • 2020-05-26
              • 1970-01-01
              • 2020-11-17
              • 2013-04-29
              • 2020-12-10
              • 2016-02-07
              • 1970-01-01
              • 2010-12-21
              相关资源
              最近更新 更多