First of all , can we really use copyWith() method if we use Riverpod?. Yes, we can. Definitely we can. CopyWith() we use to create immutable objects.
It means these objects are not editable. Actually copyWith() is independent of any state management package.
It’s exactly the same way if you use it with BLoC. Typically we see that, BLoC uses copyWith() method a lot.
Here we will see how we can use copyWith() method in Riverpod. To do it, first we have to define our states.
What’s our states? Actually, states hold our objects or variables that should be changing over the time as the user interacts. And they should be shareable too.
Let’s take a look at a simple class, that encapsulates the all the objects needed for SignIn screen.
class SignInState extends Equatable {
const SignInState({
this.email="",
this.password="",
});
final String email;
final String password;
SignInState copyWith({
String? email,
String? password,
}) {
return SignInState(
email: email ?? this.email,
password: password ?? this.password,
);
}
@override
List<Object> get props => [email,password];
}
The above class, we call SignInState and it holds two variables email and password. We need this for Login.
These two variables are declared as final which means if we want to change the value later, we won’t be able to change.
Then how about if your login information is wrong and you need to call the related sign in method again? And what if your password is wrong but email is right? Can we reuse the values? yes.
This is where copyWith() method comes into play.
Now let’s take a look at our notifier class.
class SignInNotifier extends StateNotifier<SignInState> {
SignInNotifier() : super(const SignInState());
void emailChanged(String? email) {
state = state.copyWith(email: email);
}
void passwordChanged(String? password) {
state = state.copyWith(password: password);
}
}
You see that this SignInNotifer class extends StateNotifier and takes the SignInState as state class. At this time, you might be thinking this is exactly look like Cubit.
Here we that we have state object as well. We have this state object available because of StateNotifier. And because of state object we can access anything in SignInState class including the method copyWith().
And then now we need to expose this SignInNotifier class to the UI using StateNotifierProvider. Let’s take a look
final SignInProvider =
StateNotifierProvider<SignInNotifier, SignInState>((ref) {
return SignInNotifier();
});
We call it SignInProvider. And now from the UI you may call like below to change password or email
ref.read(SignInProvider.notifier).emailChanged(value);
ref.read(SignInProvider.notifier).passwordChanged(value);
Here the value is coming from a TextField. And as you type in, you will see that you are passing the email and password value to the controller.