Skip to main content
Flutter Basics – Complete Beginner to Advanced Guide
CHAPTER 06 Beginner

Stateless Widgets vs Stateful Widgets

Updated: May 16, 2026
20 min read

# CHAPTER 6

Stateless Widgets vs Stateful Widgets

1. Introduction

A beautifully designed app is useless if it cannot react to the user. When a user clicks a "Like" button, the heart icon needs to change from grey to red. When they type in a search box, the text needs to appear on the screen. In Flutter, widgets are *immutable*—meaning once they are drawn, they cannot change. How do we create dynamic apps if widgets cannot change? We destroy the old widget and build a brand new one in its place instantly! In this chapter, we will master Stateless Widgets vs. Stateful Widgets. We will learn how to hold data (State), how to trigger a UI rebuild, and code the classic Flutter Counter App.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define what "State" means in mobile development.
  • Differentiate between StatelessWidget and StatefulWidget.
  • Understand how to use the setState() method to trigger UI rebuilds.
  • Convert a Stateless widget into a Stateful widget.
  • Build a functional Counter App.

3. What is State?

In programming, State is simply the data that your app cares about at any given moment.
  • The number of items in a shopping cart.
  • Whether a checkbox is ticked (true or false).
  • The current score in a game.
If the State changes, the User Interface (UI) must update to reflect that change.

4. StatelessWidget

A StatelessWidget is a dumb, static box. You pass it data once, it draws itself on the screen, and it never changes again.
  • Use Cases: A static logo, a block of descriptive text, an icon, or a generic layout container.
  • It only has one core function: the build() method.
dart
123456
class MyLogo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Icon(Icons.star, color: Colors.yellow);
  }
}

5. StatefulWidget

A StatefulWidget is a smart, dynamic box. It maintains its own internal data. If that data changes, it has the power to destroy its own visual representation and call its build() method again, redrawing itself with the new data.
  • Use Cases: A checkbox, an animated loading bar, a form text input, or a counter button.

A StatefulWidget actually consists of TWO classes:

  1. 1. The Widget class (which is immutable and can be thrown away).
  1. 2. The State class (which holds the data and survives while the UI is redrawn).

6. Triggering a Rebuild with setState()

How does the State class know it is time to redraw the UI? You must tell it using a magical function called setState().
dart
123456789101112131415161718192021222324252627
class CounterScreen extends StatefulWidget {
  @override
  _CounterScreenState createState() => _CounterScreenState();
}

class _CounterScreenState extends State<CounterScreen> {
  int count = 0; // This is our STATE data!

  void incrementCount() {
    // We MUST wrap the data change inside setState!
    // This tells Flutter: "The data changed, please redraw the screen!"
    setState(() {
      count++; 
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Text("Count: $count")),
      floatingActionButton: FloatingActionButton(
        onPressed: incrementCount, // Call the function when clicked!
        child: Icon(Icons.add),
      ),
    );
  }
}

7. Widget Lifecycle Basics

Stateful widgets have a lifecycle (like being born, living, and dying):
  • initState(): Called exactly once when the widget is first inserted into the screen. Great for initializing variables or starting API calls.
  • build(): Called every time setState is triggered.
  • dispose(): Called exactly once when the widget is permanently removed from the screen. Great for stopping animations to save battery.

8. Visual Learning: The StatefulWidget Architecture

txt
1234567891011
[ StatefulWidget Class ]  (Immutable Configuration)
          |
    (createState)
          v
[ State Class ]          (Mutable Data)
  - int score = 0;       <-- Memory survives!
          |
       (build)
          v
[ The UI Tree ]          (Destroyed and recreated instantly!)
  - Text("Score: 0")

9. Common Mistakes

  • Forgetting setState: The #1 beginner mistake in Flutter. If you write count++; outside of a setState(() {}) block, the integer in the computer's RAM *will* increase, but the screen will *not* update! Flutter has no idea the data changed. You must tell it.

10. Best Practices

  • Use VS Code Snippets: Typing out the two classes required for a StatefulWidget is tedious. Simply type stful in VS Code and press Enter. The IDE will generate the entire boilerplate architecture for you!

11. Mini Project: The Counter App

Objective: Build the classic Flutter default app from scratch to understand how state works.
  1. 1. Create a new Flutter project. Delete everything in main.dart.
  1. 2. Write void main() { runApp(MaterialApp(home: CounterApp())); }.
  1. 3. Type stful and create a StatefulWidget named CounterApp.
  1. 4. Inside the _CounterAppState class, declare an integer: int points = 0;.
  1. 5. Return a Scaffold. Give it an AppBar with the text "State Test".
  1. 6. In the body, create a Center widget holding a Text widget: Text("Points: $points", style: TextStyle(fontSize: 40)).
  1. 7. Add a floatingActionButton to the Scaffold.
  1. 8. In the button's onPressed: property, write () { setState(() { points++; }); }.
  1. 9. Press Play. Tap the button and watch the number update instantly!

12. Practice Exercises

  1. 1. If you are building an app screen that just displays a static "Terms of Service" text document, which type of widget should you use?
  1. 2. If you are building a screen with a "Dark Mode" toggle switch, which type of widget must the switch be wrapped in?

13. MCQs with Answers

Question 1

In a StatefulWidget, which critical method must be called to inform the Flutter framework that internal data has changed and the build() method needs to be run again?

Question 2

Why is a StatefulWidget split into two separate classes (The Widget class and the State class)?

14. Interview Questions

  • Q: Explain the fundamental difference between a StatelessWidget and a StatefulWidget. Give a real-world UI example for each.
  • Q: Describe the Widget Lifecycle of a StatefulWidget. What is the specific purpose of the initState and dispose methods?
  • Q: A junior developer writes count++; inside a button click event, but the Text widget displaying the count never updates on the screen. Identify the architectural mistake and explain how to fix it.

15. FAQs

Q: Can I put a Stateful widget inside a Stateless widget? A: Yes! A common architecture is to have a giant StatelessWidget representing the overall screen layout, and inside it, a tiny StatefulWidget representing just the favorite button. This is highly optimized because when you click the button, only the button redraws, not the whole screen!

16. Summary

In Chapter 6, we brought interactivity to our Flutter apps. We learned the difference between static StatelessWidgets and dynamic StatefulWidgets. We explored the "Immutable Widget" architecture, understanding that to change the screen, we must redraw it. We used the magical setState() method to trigger these redraws, and successfully implemented a working, interactive Counter Application.

17. Next Chapter Recommendation

Our widgets can react, but right now we can only put one widget exactly in the center of the screen. We need lists and grids. Proceed to Chapter 7: Layouts in Flutter.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·