I have a Riverpod provider created as such:
@riverpod
class SelectedEntities extends _$SelectedEntities {
@override
Set<FileOfInterest> build(FileType type) {
return {};
}
void add(FileOfInterest entity) {
if (!state.contains(entity)) {
state = { ...state, entity};
}
}
}
I can add to the provider as expected using ref.read, if I do so, the ProviderObserver shows the output as I would expect:
flutter: selectedEntitiesProvider(PreviewGrid): {picture.jpg}
I have a PreviewGrid which uses ref.watch to look for the data from the provider. If the PreviewGrid has never been opened (I need to click on a button to show it) and I then open it, the provider is showing as empty:
flutter: PreviewGrid.build(): {}
(from a debugPrint in the build function of the PreviewGrid). If the PreviewGrid is already open though, when I select the file, everything shows up as expected:
flutter: selectedEntitiesProvider(PreviewGrid): {picture.jpg} // ProviderObserver output
flutter: PreviewGrid.build(): {picture.jpg}
What am I missing, please?
Given Riverpod providers operate outside the Widget tree, not sure why I am getting disoarate results based on Visibility...
As @Randal Schwartz correctly pointed out:
Your generated provider is defaulting to autodispose. If you're not holding a ref.watch on the provider somewhere, it will reset.
There are two solutions to this dilemma:
@Riverpod
annotation and in it the keepAlive
parameter, then your code will look like this:@Riverpod(keepAlive: true)
class SelectedEntities extends _$SelectedEntities {...}
This will allow your state to be created the first time selectedEntitiesProvider
is accessed and then held even if the provider is no longer watch
ing. Some kind of state caching!
PreviewGrid
on the widget tree, add a listener to the build
or initState
method. And your provider will live on as long as it's bugged by this widget:@override
Widget build(BuildContext context) {
ref.listen(selectedEntitiesProvider, (_, __) {});
return ...;
}