my question is about what approach to choose for app state management. Many walktrough talks about BLoC, RxDart, Redux etc.
My aim is to develop a simple app that download sometimes data from a server and keep using local storage (SQL in flutter) to handle the data (CRUD operations). Other involve few user data handled by shared preferences.
I don't need high performance / super asynchronous stream of data from a server(as shown in 90% of tutoral of BLoC logic).
Is truly neecessary to have an app state pattern and what can the best approach for my case?
Yes, BLoC, RxDart, Redux are good enough.
But we should choose the things on our requirement and here in this project, there is no need to use any three of these.
For state-management, you can use the provider package as this suits best to your requirement, and it's easy to use and implement
A very simple example to implement it is here
You can use the approach of Stateful Widgets, and do your process (in case you do not need a app with a high performance), but the best approach I would suggest is to use PROVIDERS, they are easy to implement, You can take care of the downloading process and the saving also in a easier and cleaner manner, the App will perform very well, and also works well with Stateless widgets (you can rebuild only the necessary parts in a complex widget tree).
But have your own research, and find out which will suit your App the best,
Happy Coding :)
My suggestion is to try to use a mix between Provider and BLoC, instead of using RxDart, Redux which requires too much boilerplate code and it is more used to manage streams.
The provider will allow you to share information between your widget tree, in an organized way and BLoC will help you to separate your logic from your UI, the best practice to grow in time.
I suggest content from this channel: https://codewithandrea.com/tags/provider/ He helps and provides good resources to implement an easy and understandable architecture background.
Related
I've seen many tutorials praising Bloc State management, what is so special about it and should I learn it as a beginner? if not is there any beginner friendly state management technique?
BLoC/Cubit
BLoC is great for complex state management for complex apps. However, inside the BLoC library there's a simpler way of managing state that's called Cubit (Cubit is sort of a subset of BLoC). Cubit is largely the same as BLoC except:
less boilerplate
doesn't use 2-way streams
This renders it much easier to learn, and a fantastic stepping-stone into a full-out BLoC driven state management solution.
Currently, my team and I are building a very complex app, and we use the principle: use Cubit's, unless there's a specific reason to use a BLoC. This has worked well for us (85% of our app is run with Cubit, 15% with BLoC).
In relation to other state management techniques, most people are probably going to recommend Provider or Riverpods (Riverpods = Provider on steroids). They are easier to learn than Cubit/BLoC. Except, only for simple cases (a few page app). Once your app gets complex (authentication, feeds, api calls, etc.) a Cubit/BLoC-based architecture is going to scale better and be much cleaner.
Additionally, the most-used state management system for production-level Flutter apps is BLoC/Cubit. So, if you're looking for a marketable skill, I'd default to that.
Helpful links:
Flutter package that contains BOTH BLoC and Cubit.
The tutorial series I watched to learn BLoC/Cubit (and recommend!).
I HIGHLY recommend watching this series as well that shows WHERE to put your BLoC/Cubit in an app to align with best practices and clean architecture.
Example app (understanding this will help you a lot):
Here's a simple 1-feature app I made as a proof of concept to show how Cubit specifically works. Read the project's README.md for context.
Conclusion:
Provider, GetX, Riverpods, etc. are all easier to learn and contain less boilerplate than BLoC, except they won't scale as well when your app gets more complex.
To help combat the boilerplate/complexity problem of BLoC, use Cubits instead of BLoCs in your design unless you have a specific need for BLoCs.
Cubits are quite easy to understand and can be used in most of the Flutter projects. For bigger apps I would go for Riverpod. Having independent providers gives a lot of flexibility, as they can be used in different parts of the app and you can make any future, use case or repository a provider.
I have wrote a tutorial with Flutter app on how to write a List - Details app using cubits, hooks and local database with Hive.
GETX - State Management
I would suggest Getx as I have been using it for 3 years and it's incredible.
It is effortless to learn.
I never encountered a need to use any other state management.
Features provided by GETX
State management
Dependency Injection
Theming
Clean Structure
Internationalization
Validation / Utils
Documentation
The thing is that I have an app where I need to manage data across widgets, and listen to modifications (like perform an action in widget "X" whenever the value of a variable in widget "Y" changes).
So I was thinking, instead of using a whole package and adding a library to my dependencies (I mean provider) and since dart is an Object-oriented programming language... I can use the observer design pattern (pub-sub). this way I can listen to variables' modifications and perform rebuilds only where needed!
Every interaction is highly appreciated!! THANK U!
the provider package is only there to make things easier. I think building your own, or using, a pub-sub wouldn't be any easier.
Flutter already provides a detailed introduction on state management which you should probably check out first. Start by using the tools provided by the core flutter framework. Then you will find out what benefits provider, riverpod, redux, rx, etc. bring to the table and whether they are beneficial to your use cases.
When I start programming a new application in flutter everything goes well at the beginning but when the project grows up it starts to become messy, and then I decide to delete the project to start over.
I searched about the clean architecture and design patterns but I found a lot of choices such as DDD, BLoC, and so many patterns and architectures, I didn't what is the best thing to stick with every time I enter a research process that lasts forever.
So I want to hear from you as professionals and expert coders what is the best thing to stick with and what should I do? please give some advice on how to deal with big projects in flutter?
Thank you very much
Firstly the Flutter project architecture is very subjective because it depends on your needs.
But we can find some general principles:
Use a router system : By default flutter provide a Navigator API to let you navigate through your app. But there is no real structure and when you want to use push notifications to redirect the user to your App you will be stuck.
GoRouter package delivers a very nice router system, and Google teams are thinking about implementing it into the Flutter SDK.
Take advantage of a StateManagement library : When your application will become bigger you will want to handle the state of the app more precisely. So you will be able to refresh and update the content of pages easily and without reloading the content. To do that there are a lot of packages :
BLoC
Provider
Cubit
GetX
Handle the data (like API JSON Response, or SQLite Query). A huge part of a clean architecture is the way you manage the data. If you use an API you have to deal with JSON Serialization. In a small app you can do your own system to deserialize data, but you have to implement a lot of boilerplate code. I recommend to use build_runner and json_serializable packages. This stack of plugins lets you build your data classes easily without worrying about the serialization : BuildRunner will generate this code for you.
Use a structured folder system. Personally I used the DDD pattern, because you can easily separate your data from the logic of your app, this improves your maintainability.
Schema of a Flutter Clean Architecture with DDD
I hope this will help you to develop your own architecture. To wrap up, here are some helpful resources on this topic.
https://devmuaz.medium.com/flutter-clean-architecture-series-part-1-d2d4c2e75c47
https://docs.flutter.dev/development/data-and-backend/json
https://codewithandrea.com/articles/flutter-project-structure/
It's a good idea to choose layer-first or feature-first approach for your project as step one. Mentioned link to Andrea's article is a great one - https://codewithandrea.com/articles/flutter-project-structure/
Then you choose whether you want to use Riverpod with providers or blocs and/or cubits. You can write an app with all of them, so I would recommend to try them first and then make a choice. For example, I wrote a Flutter app using cubits only.
Next, you can choose routing library, to make life easier with navigating to/from screens, deep linking etc. Either auto_route or go_router is good.
Also, make use of libraries for json serialization, data classes, injectables, as they save you from lots of boilerplate code.
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
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.