-
-
Notifications
You must be signed in to change notification settings - Fork 511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MultiProvider does not support above 168 providers #703
Comments
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 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 ? This is not happening in android !! |
I found similar issues faced by others. It maybe a limitation of flutter 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. |
Proivders are widgets. They would in Redux too. It's just that in Redux, you define a single StoreProvider instead of 168 providers. |
https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html BTW, how to have one large provider ? |
Inheritedwidget are widgets, therefore increase the size of the widget tree
Regroup multiple class into a larger one. Redux is one monolithic object |
you can have "unlimited" provider using this approach:
then
in home page you can call
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? |
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). |
@rrousselGit (I can contact you in another way if it is not scope of this issue). |
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 => flutter/flutter#85026 (comment) 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(
providers: [
Provider(...),
Consumer<Null>(builder: (ctx, _, child) {
return LayoutBuilder(builder: (ctx, _) => child);
}),
Provider(...),
],
) |
The following error appears while doing this.
|
I think earlier @rrousselGit was just giving an example. |
If you have too many providers running at the same time, it might be a sign of an issue with your app's architecture. This usually happens when you’re wrapping too many widgets under a single provider or placing them too high in the widget tree. A good practice is to keep providers as close as possible to the widgets that actually need them. This keeps things more efficient, avoids excessive memory usage, and ensures that only the necessary parts of the UI are rebuilt when something changes. Also, it’s a good idea to scope providers to the screen level whenever possible. That way, when you navigate away from the screen, the provider gets disposed of automatically, which helps free up resources. If you’re running into a stack overflow error when adding +168 providers in a MultiProvider on an iOS simulator, it’s likely due to the way the Flutter framework handles widget builds and the platform’s stack size limitations, so having too many providers can lead to a deeply nested tree, which exceeds the stack size on iOS simulators. This is less of an issue on real devices or Android, as they tend to have larger stack size allowances. There are some tips that could help you:
Another way that I discovered lately, its to create a UiModel, and then if you are updating a single attribute, you can assign a valueNotifier without creating a provider class, for example:
This is even a good approach when working with clean architecture mapping 3 types of models, one in data, another in domain, and this one in presentation layer. Hope it helps! |
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
The text was updated successfully, but these errors were encountered: