何时在Flutter中使用Provider.of <X>与Consumer <X>

时间:2019-11-08 22:02:39

标签: flutter dart flutter-provider

我仍然在扑朔迷离地关注状态管理技术,对何时以及为何使用Provider.of<X>Consumer<X>的使用感到有些困惑。我从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<X>参数设置为listen的情况下使用false,如下所示:< / p>

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

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

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

这给我带来了几个问题:

  1. 这是区分Provider.of<X>Consumer<X>的正确方法。前者不会更新UI,后者不会吗?
  2. 如果未将listen设置为false,该窗口小部件将默认重建还是不重建?如果listen设置为true怎么办?
  3. 当我们拥有Provider.of时,为什么Consumer可以选择完全重建UI?

6 个答案:

答案 0 :(得分:4)

对于您的问题:

  1. 这是区分Provider.of<X>Consumer<X>的正确方法。前者不会更新UI,后者不会吗?

Provider.of<X>取决于listen的值来触发小部件的新State.build,而State.didChangeDependencies则触发StatefulWidget

Consumer<X>总是更新UI,因为它使用Provider.of<T>(context),其中listentrue。参见完整来源here

  1. 如果未将listen设置为false,该窗口小部件将默认重建还是不重建?如果listen设置为true怎么办?

默认值为true,表示将为小部件触发一个新的State.build,为State.didChangeDependencies触发一个StatefulWidget。参见完整来源here

static T of<T>(BuildContext context, {bool listen = true})

  1. 为什么我们有Provider.of时,Consumer可以选择完全重建UI?

RémiRousselet的answer涵盖了很多内容。

答案 1 :(得分:4)

Provider.of<>

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

消费者<>

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

答案 2 :(得分:3)

没关系。但是要快速解释一下事情:

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

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

Provider.of

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

消费者

  • 允许重新构建更精细的小部件
  • 解决了大多数BuildContext滥用问题

答案 3 :(得分:2)

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

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

就像上面的示例一样,我们只需要更新Single Text Widget的值,因此在此处添加使用者而不是其他小部件也可以访问的Provider。

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

答案 4 :(得分:2)

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

请参阅本文以获取更多许可 https://blog.codemagic.io/flutter-tutorial-provider/

答案 5 :(得分:2)

我们在这里需要了解 3 件事。

When you wrap Provider around a widget it sets up a reference to a widget tree and a variable whose changes you want to refer to.

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

Provider.of<object>(context) with and without listen gives you a reference to the above-declared Provider object and a widget tree where it can be accessed from. But as said by others, it rebuild the whole widget tree it sits on top of when listen is not false.

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

The consumer acts like a more granular listener and be applied to a fixed widget to help avoid unnecessary rebuilds.