DEV Community

Cover image for Common Flutter Mistakes Beginners Make (And How to Avoid Them)
Bestaoui Aymen
Bestaoui Aymen

Posted on

Common Flutter Mistakes Beginners Make (And How to Avoid Them)

Flutter is a powerful framework, but like any tool, it comes with its learning curve. If you’re just getting started, it's easy to run into pitfalls that can slow you down or create bugs that are hard to trace.

In this post, we'll cover 10 common mistakes Flutter beginners make, and how you can avoid them to write clean, efficient, and bug-free code.


🚫 1. Rebuilding Too Much with setState

The Mistake:

setState(() {
  counter++;
  heavyList = expensiveComputation();
});
Enter fullscreen mode Exit fullscreen mode

Beginners often wrap every change in setState(), causing the entire widget to rebuild—even parts that didn’t need to.

The Fix:

Separate stateful logic into smaller widgets or use state management (like Riverpod, Bloc, or Provider) to isolate state.


📦 2. Overusing Column/Row Without Constraints

The Mistake:

Column(
  children: [
    ListView(...),
    Text('Bottom'),
  ],
)
Enter fullscreen mode Exit fullscreen mode

This leads to a “Vertical viewport was given unbounded height” error.

The Fix:

Wrap scrollable widgets like ListView with Expanded or give them a fixed height:

Expanded(
  child: ListView(...),
)
Enter fullscreen mode Exit fullscreen mode

🌀 3. Using BuildContext After await

The Mistake:

onPressed: () async {
  await Future.delayed(Duration(seconds: 1));
  Navigator.of(context).pop(); // ⚠️ Might crash if context is no longer valid
}
Enter fullscreen mode Exit fullscreen mode

The Fix:

Check if the widget is still mounted:

onPressed: () async {
  await Future.delayed(Duration(seconds: 1));
  if (!mounted) return;
  Navigator.of(context).pop();
}
Enter fullscreen mode Exit fullscreen mode

🧱 4. Ignoring Keys When Needed

The Mistake:

When using ListView.builder() with items that change position, Flutter can render the wrong item.

The Fix:

Use Key properly to help Flutter track widgets:

ListView.builder(
  itemBuilder: (context, index) {
    return ListTile(
      key: ValueKey(items[index].id),
      title: Text(items[index].name),
    );
  },
)
Enter fullscreen mode Exit fullscreen mode

🌊 5. Forgetting to Dispose Controllers

The Mistake:

final controller = TextEditingController();

@override
void dispose() {
  // controller.dispose(); ❌ Oops!
  super.dispose();
}
Enter fullscreen mode Exit fullscreen mode

Memory leaks and performance issues can follow.

The Fix:

@override
void dispose() {
  controller.dispose();
  super.dispose();
}
Enter fullscreen mode Exit fullscreen mode

Or use flutter_hooks to manage them safely.


⚙️ 6. Not Using const Where Possible

The Mistake:

return Text("Hello");
Enter fullscreen mode Exit fullscreen mode

Repeatedly building non-const widgets impacts performance.

The Fix:

return const Text("Hello");
Enter fullscreen mode Exit fullscreen mode

Use const everywhere it makes sense for build-time optimization.


🗃️ 7. Nesting Too Many Builders

The Mistake:

StreamBuilder(
  stream: ...,
  builder: (context, snapshot) {
    return FutureBuilder(
      future: ...,
      builder: (context, snapshot) {
        return Consumer<MyProvider>(
          builder: (context, value, _) {
            return ...
Enter fullscreen mode Exit fullscreen mode

This causes unreadable code and rebuild chaos.

The Fix:

Use dedicated widgets for each logic block and lift them up when possible.


🎯 8. Misusing FutureBuilder for Constant Values

The Mistake:

FutureBuilder(
  future: Future.value(true),
  builder: ...
)
Enter fullscreen mode Exit fullscreen mode

No need for FutureBuilder if the value is static or already available.

The Fix:

Just use if/else, ternary operators, or assign the value to a variable beforehand.


🎨 9. Not Testing on Multiple Screen Sizes

The Mistake:

Designing for one screen size (e.g., a Pixel 5 emulator) and then realizing it breaks on tablets or landscape mode.

The Fix:

  • Use MediaQuery
  • Test on multiple device profiles
  • Consider using LayoutBuilder for responsiveness

🧪 10. Avoiding Testing Altogether

The Mistake:

Skipping testing completely because “it works on my machine.”

The Fix:

Start small with:

  • unit tests for pure logic
  • widget tests for UI
  • integration tests for full flows
flutter test
Enter fullscreen mode Exit fullscreen mode

✅ Final Thoughts

Every beginner makes mistakes—what matters is learning from them. Flutter is incredibly forgiving and flexible once you understand its core concepts.

If you’ve made any of these mistakes before (we all have!), now you know how to avoid them.


Did I miss a common mistake you faced? Drop it in the comments!

Top comments (0)