provider
provider copied to clipboard
MultiProvider does not support above 168 providers
Describe the bug If we add more than 168 providers to Multi Provider then on iOS simulator it does not work.(stack overflow error) On real device and on Android it works fine
To Reproduce
Just add more than 168 providers and try to run on iOS simulator. Also please use Navigator.
Expected behavior It should support more than 168 providers. If don't use multi-provider, and add more than 168 providers then it works
It's not really a bug, rather it's a limitation of the widget tree, which depends on your device
Optimisations are possible, but removing the limit is difficult
@rrousselGit Can you please locate me the place where this limitation code is present ?
I would like to remove this limitation for my project.
There's no particular place.
But then why is the problem only happening in debug mode in iOS simulator ? I have tried in iPhone 13 Pro Max, iOS 15
This is not happening in android !!
I found similar issues faced by others. It maybe a limitation of flutter https://github.com/flutter/flutter/issues/85026 https://github.com/flutter/flutter/issues/73734
But I think this should be fixed some where, either here or by flutter.
That "limit" is built directly in the device. It's not Flutter or Provider that decides to throw a StackOverflow error, but the device that tells that it reached its stack limit
But shouldn't the framework and packages be built depending upon the device configuration rather than the other way around ?
The problem with provider package is that it increases this hierarchy without considering this limitation.
What exactly do you expect provider to do here?
I expect that if flutter is not able to support deep hierarchy widget tree, then provider shouldn't keep increasing the widget tree. Maybe find a better way to do what it is doing but not increasing the hierarchy. e.g. redux in react
Proivders are widgets. They'll always increase the hierarchy
They would in Redux too. It's just that in Redux, you define a single StoreProvider instead of 168 providers. You could have one large provider if you wanted to
https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html Inherited widgets don't increase widget tree.
BTW, how to have one large provider ? Can you please give me an example ?
Inheritedwidget are widgets, therefore increase the size of the widget tree
BTW, how to have one large provider ? Can you please give me an example ?
Regroup multiple class into a larger one.
Redux is one monolithic object
you can have "unlimited" provider using this approach:
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => AppProvider()),
],
child: MaterialApp(...),
)
then
class AppProvider extends ChangeNotifier {
late HomeProvider homeProvider;
late SecondProvider secondProvider;
AppProvider() {
homeProvider = HomeProvider();
secondProvider = SecondProvider();
}
}
in home page you can call
HomeProvider get provider => context.read<AppProvider>().homeProvider;
haven't test for hundreds provider yet, but what do you think? @rrousselGit
is this happen for real devices in release mode ?
Getting StackOverflowError after upgrading to Flutter 3.7 only on iOS. We also use MultiProvider with many global providers. @rrousselGit what is your advice to solve it? Scoping providers? Stop using MultiProvider and using lots of individual providers?
@tuhinansu-gourav said that changing to many individual providers worked.
You can stop using MultiProvider yes. That should raise the limit quite a bit, at the cost of readability.
@rrousselGit So, since providers nests each other, the only solution that escalates is not to have dozens of providers above the same widget tree. Am I right?
You can stop using MultiProvider yes. That should raise the limit quite a bit, at the cost of readability.
I don't see why it would raise the limit. Wouldn't the providers be nested anyway?
MultiProvider works by adding extra widgets under the hood
Not using it means those extra widgets are no-longer here, which gives you a few extra slots for providers
@rrousselGit if I migrate to Riverpod (I haven't read the docs yet), would it solve the problem of the widget tree? Or Riverpod does have the same InheritedWidget problem for multiple providers?
It would solve the problem yes.
Riverpod only uses a single widget for storing providers (ProviderScope). As opposed to with Provider where every provider counts for 2-3 widgets
@rrousselGit (I can contact you in another way if it is not scope of this issue). We use ChangeNotifier for almost everything regarding state management in our project. I know in RiverPod you wanted to push immutability, and I think that's pretty nice. I was just wondering if sometime in the future you are thinking about removing ChangeNotifier from Provider?
Why would I do that?
@rrousselGit , do you think keeping the MultiProvider but using lazy: true on the ChangeNotifierProviders would help with this case?
No because lazy or not has no impact on the depth of the tree
The issue is known by flutter. There is a fix That permits to "reset" the tree depth, avoiding stackoverflow => https://github.com/flutter/flutter/issues/85026#issuecomment-885428067
This could be a good fix for provider, wrapping the child in MultiProvider in a LayoutBuilder
The problem is, that would make MultiProvider insert RenderObjects – which is UI related. Providers are currently UI-independent at the moment (no RenderObject involved).
But you can do that on your own. MultiProvider supports inserting a Consumer too:
MultiProvider(
providers: [
Provider(...),
Consumer<Null>(builder: (ctx, _, child) {
return LayoutBuilder(builder: (ctx, _) => child);
}),
Provider(...),
],
)
The problem is, that would make MultiProvider insert RenderObjects – which is UI related. Providers are currently UI-independent at the moment (no RenderObject involved).
But you can do that on your own. MultiProvider supports inserting a Consumer too:
MultiProvider( providers: [ Provider(...), Consumer<Null>(builder: (ctx, _, child) { return LayoutBuilder(builder: (ctx, _) => child); }), Provider(...), ], )
The following error appears while doing this.
The following ProviderNotFoundException was thrown building Consumer<Null>(dirty): Error: Could not find the correct Provider<Null> above this Consumer<Null> Widget
I think earlier @rrousselGit was just giving an example. The new error that you are getting is that, a consumer can only access providers that are above it in widget tree. You can check it in widget inspector.