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 ]
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
},
CodePudding user response:
You can use a private variable setter
, then call notifyListeners
in the setter after updating the variable like so:
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!;
CodePudding user response:
Firstly, you should not use ref.watch inside any onTap callbacks. Use ref.read here instead. 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. 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. Use your second code block as a reference in future. This is the correct and safest way.