为什么Flutter riverpod直接赋值不起作用,而方法起作用

9jyewag0  于 2022-12-14  发布在  Flutter
关注(0)|答案(2)|浏览(204)

请检查以下两个示例。

  • 第一个示例不重新生成小部件[可能“侦听器”未被“通知”]
  • 第二个示例按预期工作

就我的理解,我认为这两个都可以。谁能告诉我我缺少的理解吗?提前谢谢。
示例一(重建)[用户界面更改不生效]

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

样本2(重建)[工作正常]

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

gg58donl1#

首先,你不应该ref.watch在任何onTap回调中使用www.example.com,而应该在这里使用ref.read。请阅读本文以了解为什么会出现这种情况。
其次,在第一个代码块中,您可以编写:

UserModel().notifyAllListeners();

UserModel()创建了一个新对象,并为这个新对象调用notifyAllListeners()。这个新对象在这个小部件的build方法中没有被监视。这就是为什么你发布的第一个代码块无法重建小部件。
第三,作为最佳实践,像notifyListeners()这样的方法和对任何类中字段的直接赋值都应该在类的代码内部完成。使用第二个代码块作为将来的参考。这是正确和最安全的方法。

vof42yt1

vof42yt12#

您可以使用私有变量setter,然后在更新变量后在setter中调用notifyListeners,如下所示:

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

现在,这应该行得通:

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

相关问题