I have the below Riverpod annotation for the provider. I would like to update the values in one page and get the updated value in next page.
@riverpod
class UserCardSheetInfo extends _$UserCardSheetInfo {
@override
UserCardInputSheet build() => const UserCardInputSheet(issuerKey: '', cardKey: '');
void updateIssuer(String value) {
state = state.copyWith(issuerKey: value);
print("issuerKey:${state.issuerKey}"); // has value
print("cardKey:${state.cardKey}"); // empty
}
void updateCard(String value) {
state = state.copyWith(cardKey: value);
print("issuerKey:${state.issuerKey}"); // empty
print("cardKey:${state.cardKey}"); // has value
}
}
@freezed
class UserCardInputSheet with _$UserCardInputSheet {
const factory UserCardInputSheet({
required String issuerKey,
required String cardKey,
}) = _UserCardInputSheet;
}
I the first page, I am updating the value as below.
class _SelectableIssuersList extends ConsumerStatefulWidget {
const _SelectableIssuersList();
@override
ConsumerState<_SelectableIssuersList> createState() => _SelectableCardsListState();
}
class _SelectableCardsListState extends ConsumerState<_SelectableIssuersList> {
@override
Widget build(BuildContext context) {
return SomeWidget(
onClick: (newIssuer) => setState(() {
ref.watch(userCardSheetInfoProvider.notifier).updateIssuer(newIssuer);
}),
);
}
}
In the next page, I am trying to read the updated value. But I am always getting an empty class without the values.
class _SelectableCardsList extends ConsumerStatefulWidget {
const _SelectableCardsList();
@override
ConsumerState<_SelectableCardsList> createState() => _SelectableCardsListState();
}
class _SelectableCardsListState extends ConsumerState<_SelectableCardsList> {
@override
Widget build(BuildContext context) {
// ====> Always Empty
print(ref.watch(userCardSheetInfoProvider).issuerKey);
return AnotherWidget();
}
}
How should I be handling the value read/write using Riverpod?
2
Answers
The issue is resolved after keeping the provider alive. This helped to keep the same state when navigating to other screens.
riverpod is designed to handle immutable data and not mutable.
it does it by comparing the previous and the next states.
the problem with the line
state.issuerKey = value
is that you change the previous state as well as the next so the comparison will always return trueand riverpod will not rebuild.
a correct implementation of your provider will be:
also, in your case, you don’t need to use
StatefullConsumerWidget
,ConsumerWidget
is enough