So you want to learn Flutter. Maybe you’ve seen a cool job opening for Flutter developers or wanted to try how it compares to native development of Android or iOS apps. You’ve started learning Flutter and it seemed pretty cool, right? You wanted to learn more and more and the hunger for Flutter knowledge doesn’t stop? Well it might be a time to slow down and reflect on what you’ve learned. Maybe try to be a bit self critical. See what could’ve been done better. After all, Flutter is a new technology and many times there isn't a right or wrong answer. Here are some mistakes I made as a Junior Flutter Developer:
1. Ignoring native development
A few years before I started learning Flutter, I started developing Android apps using Kotlin. Unfortunately it didn't last long because I was a student and didn’t have enough free time to further increase my Android skills.
Today, I can see clearly that the basics of both Android and iOS would be a useful background. Maybe it isn’t the worst mistake not to learn native development but it sure does help. As you develop more and more Flutter projects, you’ll find yourself opening android and ios folders more often. Sometimes you may have to tweak native code to get desired behavior. (A good example would be implementing native splash screens - although nowadays, there is a package for everything.)
Overall, it is generally considered a good practice to have experience with native development before starting Flutter. Surely, it isn’t a must to get you going with Flutter but at some point you’ll need to understand the concepts of native development.
2. Not making everything a widget
One way of implementing a DRY principle in programming is always extracting a repeating logic into a function. This led me to extracting repeating UI components into functions but I’ve realized soon that this kind of approach is no good.
Flutter is a bit different in that way. Since we want our app to be as performant as it can be, we need to minimize the amount of rebuilds it’s making. For example, imagine having a screen with a button that is changing color on click. Performance wise, you’d only want to rebuild that button when the color has changed. If you use something like the code below, the whole screen will rebuild every time!
Scaffold(
body: Column(
children: [
...,
...,
...,
ElevatedButton(
style: ElevatedButton.styleFrom(primary: color),
onPressed: () {
setState(() {
changeColor(),
});
},
child: const Text(‘Button’),
),
],
),
);
The key is to extract that button in a separate widget and move the color changing logic into that new widget. As you call setState(), only that widget will be rebuilt and the rest won’t. Now, it probably doesn’t sound that important, but when you have some heavy-computing happening and/or the screen itself is rebuilding frequently (animations can be performance heavy), there is a possibility that the app will lag. To further understand this topic, I would recommend this video: https://www.youtube.com/watch?v=IOyq-eTRhvo. I myself started to use this approach only after seeing this video (yes I’m ashamed) because I never, to that day, had a reason to optimize my app.
3. Lack of state management
If you’ve read my previous mistake, you may wonder how you can change the color of our button widget from another widget that is higher in widget tree. What happens if some other component needs to change the color of the button? Well, the solution to that problem isn’t trivial.
That’s why we use state management solutions. Some of the most popular state management solutions are Provider, Riverpod, BLoC and GetX.
When I first started my Flutter journey, I only used setState() as my state management approach. As far as I think, it isn’t bad to start that way because then you know exactly what happens with your widgets and how Flutter is rebuilding and drawing your screens.
As soon as you start making more complex apps, everything will become a mess. You’ll have trouble finding anything in your code since it will probably be spaghetti code. The best way to clean that mess is to implement a state management solution. That way you’ll decouple UI components from the business logic and everything will have its place in your project.
I personally started with BLoC but didn’t find it that helpful nor simple. A few months ago I was introduced to Riverpod and never looked back. Anyway, it’s a matter of personal preference and you should find what works for you and stick with it.
4. Using too many packages
Flutter is a framework developed with simplicity in mind. If you aren’t new to Flutter, you’ve probably heard: There is a package for everything - and yes, there almost literally is. When developing a new feature chances that someone already implemented it and made a package for others to reuse it are pretty high. It's as simple as plug'n'play.
Of course, if you want to become a good Flutter developer and know what’s happening under the hood of those packages, you’ll probably want to implement it yourself. It might be time consuming but it is the best way to actually learn fundamentals.
When I first started learning Flutter, I was a victim of this mistake myself. I would start working on a new feature and the first thought that would cross my mind was: Let’s check if there is a package for that! Unfortunately, the package was there in 90% of situations. Just later, I realized that no package is without its flaws.
Imagine the situations where you need to develop a feature which already has a package dedicated for it but it just lacks that little thing that you need. You have no choice but to write it on your own. Having experience doing things yourself will definitely come in handy.
5. Not being consistent
Flutter provides you with package flutter_lints in every new project by default if you are using Flutter 2.3.0-12.0.pre or newer. It provides the latest set of recommended lints that encourage good coding practices.
When I first started, I wanted to learn as much as possible and go through the Flutter framework as quickly as I could. The result of that was inconsistent code with a lot of bad practices which were error prone. My life changed when I started using the lint package.
No more single quotes double quotes dilemma. Choose one and stick with it. (Personally I use single quotes in Flutter projects because imports are automatically added with single quotes.) Functions without return types don’t exist anymore. I started avoiding using var. And so on and so forth.
Personal favorite lints of mine are always_declare_return_types
and always_specify_types
.
Introduction of lints in my projects made my code cleaner, better and most important more consistent.
Like in every other project (or anything you do in life) consistency is key.
Conclusion
To conclude, don’t be discouraged if you are making some of these mistakes as well but always strive to learn more and do more. These were my top 5 mistakes and I hope you can learn from them, because I most certainly did. Feel free to share some of the mistakes you’ve made when starting with Flutter!
Top comments (0)