I'm learning Riverpod, so I'm trying different things to see how it works. Let's say I have the following class in my app;
class User {
String _name = "";
String _email = "";
String get email => _email;
String get name => _name;
set email(String value) {
_email = value;
}
set name(String name) {
_name = name;
}
}
So, I created a StateProvider to control the changes made in a User object:
final userProvider = StateProvider<User>((ref) {
return User();
});
That is accessed this way:
final user = ref.watch(userProvider);
...
Text('Value: ${user.name}'),
However, when I change the provider's state, it does not rebuild my UI.
ref.read(userProvider.notifier).state.name = 'John Doe'
What am I missing?
If you notice carefully, you are creating StateProvider of User
. Therefore, changing single instance fields doent means it is different instance(new User) and that's why changing/updating fields doesn't refresh the UI. You need to pass new instance to update the UI.
You can do
final currentData = ref.read(userProvider);
ref.read(userProvider.notifier).state =
User(name: 'new name', email: currentData.email);
But I prefer with copyWith
method
final currentData = ref.read(userProvider);
ref.read(userProvider.notifier).state =
currentData.copyWith(name: 'new name');
or just use update
ref
.read(userProvider.notifier)
.update((state) => state.copyWith(name: 'new name'));
And the model class
class User {
const User({
this.name = '',
this.email = '',
});
final String name;
final String email;
User copyWith({
String? name,
String? email,
}) {
return User(
name: name ?? this.name,
email: email ?? this.email,
);
}
}