Search code examples
flutterriverpodstate-management

Using a Riverpod State Provider to control changes in object


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?


Solution

  • 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,
        );
      }
    }