Provider vs. InheritedWidget - flutter

Am I wrong or if we just want to pass a value down the Widget tree, Provider is just an InheritedWidget with a dispose method?

Yes. Provider is indeed mostly features based on Inheritedwidgets.
If you want to make your own, then that's fine. But you'll quickly realize that, without provider, you'll have hundreds of useless repetitive lines.
Provider basically takes the logic of InheritedWidgets, but reduce the boilerplate to the strict minimum.

Provider is not a must, but should.
First of all, it's promoted by Flutter Team and flexible enough to handle almost any state-management solution.
It might not be fair to say that InheritedWidget with dispose because Provider has too many different use cases and inherits some optimizations probably you won't find anywhere else.
If you use InheritedWidget in large application, build methods always rebuilds whole build method. But with Provider you have Consumer widget which is can be very specific to control specific blocks of build method, so you have more efficiency. Also listeners have less complexity than InheritedWidgets'(O(N) vs O(N²)).
The problem is since Flutter was intended to be a UI framework at first, the default state management solutions are also UI oriented.
Lastly, since you'll need different state-management patterns for different projects, one package-for-all scenario is invaluable imo.

The Flutter docs have a good section about this where they're talking about state management in your app (a big part of which is passing values down the tree).
Flutter has mechanisms for widgets to provide data and services to their descendants (in other words, not just their children, but any widgets below them). As you would expect from Flutter, where Everything is a Widget™, these mechanisms are just special kinds of widgets—InheritedWidget, InheritedNotifier, InheritedModel, and more. We won’t be covering those here, because they are a bit low-level for what we’re trying to do.
Instead, we are going to use a package that works with the low-level widgets but is simple to use. It’s called provider.
So as of late 2021, it seems the recommendation is to use the provider package unless you need lower level access- in which case you could use the Inherited* widgets. For example, if you wrote your own version of provider then you'd need that lower level access.
The doc I quoted above is at https://docs.flutter.dev/development/data-and-backend/state-mgmt/simple#accessing-the-state

Related

MultiBlocProvider's misusing cases

We know that, we need to put BlocProvider instance on top of widget tree's part, which we want to get access data inside this part of tree. What if we use all BlocProvider instance on top of whole tree, even most of them are only necessary for some small bottom parts of tree. Is it considered as mistake, because of we are passing data across whole tree(despite it is unnecessary) every time we call it, or there will be zero performance differences between putting all blocProvider on top and putting BlocProviders only on appropriate tree parts.
It is considered bad practice to put everything at the top of the tree for several reasons. It breaks several common good programming practices, SOLID amongst others. You e.g. don't have all your variables and class instances in your applications as global variables.
And when it comes to performance, yes it can have a negative effect on performance. If and how much is of course not possible to say before hand because it depends on how many, what the blocs do, how they are used and etc.
Some should obviously be at the top, so they should be. But not all. So provide them only where they are needed as it will be better performance wise and will keep your code cleaner.
Edit:
This is from the creator (Felix Angelov) of flutter bloc:
The main disadvantages of providing all blocs globally are:
The blocs are never closed so they are consuming resources even if they aren't being used by the current widget tree
The blocs can be accessed from anywhere even if the state of the bloc is scoped to just a particular feature
The blocs typically end up needing some sort of "reset" event to revert back to the initial state which is not necessary if they are
properly scoped and automatically disposed by BlocProvider
My recommendation is to create a bloc per feature and provide that
bloc only to the specific subtree that needs it. Hope that helps 👍

Flutter best architecture patterns

I came from MVC and VIPER world and now I am new to Flutter cross-platform development. I really like declarative things it brings (like SwiftUI for example does as well). I see a lot of advantages in React architecture that Flutter uses to update UI with the most recent data. Though I still try to understand a conception of widgets. In my head, a word widget is more about UI things, but the documentation says that all in Flutter is a widget.
Let me highlight a simple example. Also, let's forget about declarative UI things.
In the iOS world using Objective-C or Swift, we usually separate a lot of layers such as data layer, UI layer, service layer, some helper layers and etc.
As you may notice we can't simply call these layers widgets, but looks like flutter can, but I may be wrong.
In the iOS world, I would like to use VIPER or some similar architecture pattern to separate different layers or add some services which request some data for me or do save it into the database.
What are the similar approaches or architecture patterns which I can use to follow best practice recommendations to achieve the best result, because as for me if we call some service which saves data to the database as a widget it's a bit strange. I would like to call it more service rather than a widget.
Do I need to write a widget for all such things? Or did I get it wrong?
Do I need to write widget for all such things? Or did I get it wrong?
Let me start by saying that flutter is flexible enough to allow you to adopt any pattern you have been using before and from MVVM, MVC, Redux, Mobx, Bloc, Provider, Riverpod etc pp there are many patterns out there which you can lean on.
Q: Do all services have to be widgets?
A: It depends.
Lets talk about "getting" the services first (dependency injection)
Using Widgets is just one way of doing dependency injection in Flutter which has the huge benefit of being scoped (only available to the children of the widget) and also of being disposed when this part of the widgettree is no longer needed (a bit over simplified).
There are other DI systems like getIt which don't rely on the widget tree - and you can do fancy stuff with getIt which is cumbersome to do in many of the others which rely on the build context to provide access to the object.
Imho in most cases you would not want to have your logic/ service in a widget but in a separate class which is then "provided" via a widget (e.g. using Provider, or by injecting it via getIt into the widget).
About "best practices":
There are many cool patterns which all have their pros and cons.
If you have a big team or the developers are changing often you might want to use a more rigid and biased system like BLOC (using the bloc library) - if you are solo or have enough time on your hands to do your own research, there might be patterns which better suit your needs. There is no one size fits all answer to this question.
For further research I would point towards the Flutter Architecture samples and the corresponding Github repo, there might be more examples in the Pull Request section

Purpose of scoped_model/provide packages if built-in state management works

New to Flutter, so please forgive the question.
I'm playing around with the need to manage state (variables/objects) across the entire app using the Stateful widget - it's a bit cumbersome, but I get the method.
I see there are packages providing similar functionality (scoped_model and provide) - what do these bring to the mix and what problem do they solve? Before embarking on one particular approach, I guess I'm asking what the seasoned Flutter devs are using and why?
Thanks
It's mainly about scalability & performance of your application. Using StatefulWidget is fine for small apps, but imagine if you had a widget tree of a depth of 30, and only 2 leaf widgets need to know about some counter value, and they're both at opposite ends of the widget tree. With StatefulWidget approach, you'd have to place the value at the top of the tree and pass it down the entire tree so the 2 widgets can get it. Then, after a while, you need another widget in a totally unrelated branch of the tree to get counter as well - now you need to modify that entire branch to also pass down the value. Then, later on, you decide to move one of the original leaves to a different place - again, you have to modify your entire codebase to accommodate that.
Using InheritedWidget makes that both provider and scoped_model use, you can instead just inject counter at the top of the tree and have the widgets that require it simply extract the value from their context using a Consumer or the scoped_model equivalent. This will also solve another issue: now that none of the intermediate widgets know about counter, they no longer need to rebuild when the value changes. You can now move your widgets around and add/remove dependencies on counter as you please and not mess with unrelated widgets as you do that.
You can even go a step further and use blocs instead. I recall reading an article that compared all approaches and found that blocs can further improve performance of your app by eliminating some builds, though it can be a little daunting to understand what's going on in the bloc pattern at first.
Using StatefulWidget only is not bad.
You don't have to use provider/scoped_model.
StatefulWidgets are very powerful and scalable by default.
Their shortcomings are:
they are very verbose
it is difficult to reuse stateful logic between stateful widgets (although there are variants for it, like flutter_hooks)
refactoring can be painful
These are things that InheritedWidgets solve, so provider/scoped_model too.
But as you can see, these are mostly quality of life issues.
If you can support them, it's fine to use StatefulWidget only.

what is the danger of an application without State management

I was new to the flutter so I build a full application without using state management, all my screens in the application built with the stateful widget
what is the danger of that if many users used it?
You risk not being able to scale your code well. From passing data down the widget tree to passing data to screens etc., this will require a lot of lines which will lead to un-maintainable code. For small projects though, you don't really have to use state management libraries such as BLOC and Scoped Model.
As the project scale, I believe you will have performance issues due to using setState() and without inherited widget your UI will re-render again every small change or action in your screen.
Also, Your code will get complicated as project scale because you are not separating your logic in a separate file (using bloc, provider or whatever), It will be a mess as UI and business changes.
Most users won't know the internal architecture of your app unless they are good programmers themselves. But the goal of building applications is to attract users, and expand customer base. And this will require you or your company to add additional features in the future to accommodate their needs, and when you try to make even a subtle change to the source code, it will take more time and you will be prone to add new bugs to your application as your models and views are all mixed together.
Another reason is that you can't (as far as I know) test an app which doesn't have any type of state management.

Which one is faster and performant Provider, bloc pattern or flutter_redux?

I need manage the states globally, I find a lot of way, in terms of managing the state by using Provider bloc pattern redux and etc.
But actually I dont know, which one is faster and performant?
Example: I am working on chat application, which I have to manage socket connection messages online offline status all as globally. the states need to be accessible from all screen, like ChatList screen, ChatBox screen and more...
I didn't test them all performance wise. And i do not think it will make much of a difference.
Provider works with inheritedwidget as scoped model i think.
I love the streams for the versatility of the data flow.... i think the key part for performance is to keep the rebuilding/painting of the widgets that require it at the lowest level of the tree.
get_it package should help you to keep those streams accessible everywhere, is a great simple package to keep neat model access, regarding the state management solution.
For instance, i believe that generating statelessstateful widgets instead of functions that returns widgets to make the layout, provides more performance, for the separation of buildcontexts.
In any case, the framework is super optimized and performant... if u run into any issue, u can easily track it down with the devtools and the community is very supportive.
Btw, take my basic reply with a grain of salt, as I've been only playing with flutter/dart for a week.