简体   繁体   English

为什么 Flutter riverpod 直接分配不起作用但方法可以

[英]Why does Flutter riverpod direct assignment does not work but methods do

Please check the two samples below.请检查下面的两个示例。

  • The first sample does not rebuild the Widgets [Possibly 'listeners' are not being 'notified']第一个示例不重建小部件 [可能“听众”没有被“通知”]
  • The second sample works as expected第二个样本按预期工作

To my understanding, i think all these two should work.据我了解,我认为所有这两个都应该有效。 Can someone brief me on the comprehension I'm lacking?有人可以向我介绍一下我缺乏的理解吗? Thanks in advance.提前致谢。



Sample one (Does not rebuild) [ui changes do not take effect ]示例一(重建)[ui 更改不生效]

onTap: (String? newValue) {
ref.watch(UserProvider).selectedMaritalStatusValue = newValue!;
UserModel().notifyAllListeners(); //triggers notifyListeners
 },

Sample Two (Does rebuild)[working fine]样本二(重建)[工作正常]

onTap: (String? newValue) {
ref.watch(UserProvider).setMaritalStatus(newValue!); // 'setMaritalStatus' has notifyListeners trigger within
 },

You can use a private variable setter , then call notifyListeners in the setter after updating the variable like so:您可以使用私有变量setter ,然后在更新变量后在 setter 中调用notifyListeners ,如下所示:

class UserProvider extends ChangeNotifierProvider{
    String? _selectedMaritalStatusValue;
    String? get selectedMaritalStatusValue => _selectedMaritalStatusValue;
    set selectedMaritalStatusValue(String? newValue){
      _selectedMaritalStatusValue = newValue;
      notifyListeners();
    }
}

Now, this should work:现在,这应该有效:

ref.watch(UserProvider).selectedMaritalStatusValue = newValue!;

Firstly, you should not use ref.watch inside any onTap callbacks.首先,您不应该在任何 onTap 回调中使用 ref.watch。 Use ref.read here instead.在这里使用 ref.read 代替。 Read this for clarity on why this is the case.阅读本文以清楚地了解为什么会这样。

Secondly, in your first code block where you write:其次,在您编写的第一个代码块中:

UserModel().notifyAllListeners();

UserModel() creates a new object altogether, and notifyAllListeners() is being called for this new object. This new object is not being watched inside the build method of this widget. UserModel() 共创建了一个新的 object,并且正在为这个新的 object 调用 notifyAllListeners()。这个新的 object 没有在这个小部件的构建方法中被监视。 This is why the first code block you posted fails to rebuild the widget.这就是为什么您发布的第一个代码块无法重建小部件的原因。

Thirdly, as a best practice, methods like notifyListeners() and direct assignments of fields in any class should be done inside the class's code.第三,作为最佳实践,notifyListeners() 之类的方法和任何 class 中字段的直接赋值应该在类的代码中完成。 Use your second code block as a reference in future.将来使用您的第二个代码块作为参考。 This is the correct and safest way.这是最正确、最安全的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM