I'm working on a simple demo where the user logs in, sees a list of items, clicks on an item, and then sees its details. These are 3 screens but let's say two flows where one deals with login and the other with items.
I'm managing my state using provider
package. I placed a LoginRepository
provider on my root widget because that state is needed everywhere. This works great.
Now I need an ItemRepository
which should be available on the ItemListScreen
and the ItemDetailScreen
. To implement that scoping, I decided to create a common ancestor widget called ItemScreens
. This is where I placed my provider and my nested Navigator
.
I navigate my screens using Navigator.of(context)
to make sure the closes ancestor navigator is used. I fetch my provider using Provider.of<ItemRepository>(context)
to make sure the closes ancestor state is used.
This apparently does not work because I get a Could not find the correct provider
. I understand that the provider from the sibling route cannot be accessed by another sibling but here I'm nesting navigators I would expect the ItemRepository
to be placed at ItemScreens
which then handles subrouting so that these two routes can fetch providers from the parent route?
Sidenote:
Flutter documentation clearly states that providers should be lifted to achieve proper scoping. But I've never seen an example where the provider was lifted to a non-root widget. If all we can do is place providers into the root widget, that should be clearly stated.
EDIT: Re-creating providers on several widgets is kind of an alternative but that's not really scoping it's just pseudo passing by value.
EDIT: Putting all providers on the root widget with MultiProvider
isn't a good idea because it creates a global state anti-pattern. Some states should also simply not be created unless needed i.e. the user is visiting that flow/screen.