在新小部件中使用提供程序实例时哪个更好?

Posted

技术标签:

【中文标题】在新小部件中使用提供程序实例时哪个更好?【英文标题】:Which is better when using provider instance in a new widget? 【发布时间】:2022-01-17 11:19:29 【问题描述】:

假设我已经编写了如下代码。 我有一个名为 SampleProvider 的提供程序,我在我的主小部件中使用它。

class SampleProvider extends ChangeNotifier 

class MainWidget extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    SampleProvider provider = Provider.of<SampleProvider>(context);
  

然后,我想制作一个新小部件并在新小部件中使用此提供程序。 会有两个选择。 首先,我只是在新的小部件中实例化另一个提供程序,如下所示。

class NewWidget extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    SampleProvider provider = Provider.of<SampleProvider>(context);
  

或者,我可以将它作为构造函数参数从主小部件发送到新小部件。 像这样:

class NewWidget extends StatelessWidget 
  final SampleProvider provider;
  NewWidget(this.provider);

  @override
  Widget build(BuildContext context) 
  

我猜第一个选项更好,因为颤振根据其构建上下文绘制一个小部件,但我不确定。 我用谷歌搜索了很长时间,但没有成功。 谁能告诉我我是对还是错?还是他们没有区别?

【问题讨论】:

【参考方案1】:

首选第一种方案,更容易重构。

假设您需要在小部件树中移动NewWidget,如果您选择第二种解决方案,您还需要修改“参数传递”代码,而第一种解决方案则不需要。

Provider pacakage 的一个目的是避免顺便将参数传递到小部件树的深处。

【讨论】:

【参考方案2】:

取决于偏好,不像第一个或第二个。

在 initState 中获取 Provider 时出现异常。我能做些什么? 发生此异常是因为您试图从一个永远不会再次调用的生命周期中侦听提供程序。

这意味着您要么应该使用另一个生命周期(构建),要么明确指定您不关心更新。

因此,而不是:

initState() 
  super.initState();
  print(context.watch<Foo>().value);

你可以这样做:

Value value;

Widget build(BuildContext context) 
  final value = context.watch<Foo>.value;
  if (value != this.value) 
    this.value = value;
    print(value);
  

它会在它改变时打印值(并且仅在它改变时)。

或者,您可以这样做:

initState() 
  super.initState();
  print(context.read<Foo>().value);

SRC:https://github.com/rrousselGit/provider#i-have-an-exception-when-obtaining-providers-inside-initstate-what-can-i-do

【讨论】:

【参考方案3】:

如果您不将新小部件用作任何其他小部件的子级,则首选更好。 否则,第二个更好。

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案4】:

是的,我相信第一个选项是更好的方法,我想不出任何情况下您更喜欢第二个选项而不是第一个选项。

【讨论】:

以上是关于在新小部件中使用提供程序实例时哪个更好?的主要内容,如果未能解决你的问题,请参考以下文章

QDialog 在添加新小部件时将小部件涂成黑色

更改新小部件的大小

用Flutter中的新小部件替换dismissed小部件

Gridstack - 添加带有内容的新小部件

制作新小部件后清除类的列表

如何将旧的小部件迁移到新的小部件