What are some rules to follow for good app architecture in Flutter?
Thread. 🧵
If you want your code to be testable, there are various alternatives to singletons:
- constructor arguments (doesn't scale well with deep widget hierarchies)
InheritedWidget
or Provider- Service locators (e.g. get_it)
Widgets should be as dumb as possible and only be used to map the state to the UI.
Small exceptions: sometimes I include some simple currency, date, or number formatting code in my widgets if it makes life easier.
Your view models/blocs/controllers are used to update the widget state in response to events.
By ensuring that these classes don't have any UI code in them, they can be easily unit tested.
If you try to put your navigation code in the business logic, you'll have a hard time because you need a BuildContext to do so.
Solution:
- emit a new widget state
- listen to the state in the widget and perform the navigation there
Same as above. When we need to show an alert dialog because something went wrong, this is what we should do:
- emit a new error state
- listen to the state in the widget and use the context to show the alert dialog
FormState
and TextEditingController
depend on the widget lifecycle, so they shouldn't go in the view models/blocs etc.
Keep them in your widgets and offload everything else to the business logic.
Following these simple rules will force you to structure your code properly and make it much easier to test.
Found this useful? Show some love and share the original tweet 🙏
Previous | Next |
---|---|
GoRouter: go vs push |
Popular architectures for Flutter development |