Understanding Stateless & Stateful Widgets in Flutter

Introduction

Flutter is a powerful framework for building modern mobile applications, and at its core are widgets. Every UI component in Flutter is a widget, and they are mainly divided into two types:

  • Stateless Widgets (Static UI)

  • Stateful Widgets (Dynamic UI)

Understanding how these widgets work is essential for building interactive, responsive, and scalable mobile applications.

In this blog, you will learn:

  • What Stateless and Stateful Widgets are

  • When to use each type

  • How UI updates work in Flutter

  • State management using setState()

  • Real-time Flutter (Dart) examples

Previous Lesson: Layouts in Flutter: Column, Row, Stack, Expanded & Flexible Guide

StatelessWidget vs. StatefulWidget 🤓

What are Stateless & Stateful Widgets?

Definition

Stateless Widget

A Stateless Widget is a widget that does not change its state once it is built. It displays static content and does not respond to user interaction.

Flutter Apprentice, Chapter 4: Understanding Widgets | Kodeco

Key Characteristics:

  • Immutable (cannot change)

  • Lightweight

  • Faster rendering

  • No internal state

Example of Stateless Widget
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Stateless Widget Example")),
        body: Center(
          child: Text(
            "Welcome to Flutter",
            style: TextStyle(fontSize: 24),
          ),
        ),
      ),
    );
  }
}

Real-Time Use Case

  • Displaying static text

  • App logos

  • Headers and titles

  • About pages

Example: A welcome screen in a mobile app.

Stateful Widget

Definition

A Stateful Widget is a widget that can change its state during runtime. It allows dynamic updates in the UI when data changes or user interacts.

Flutter Lifecycle | Stackademic

Key Characteristics:

  • Mutable (state can change)

  • Supports user interaction

  • Rebuilds UI using setState()

Stateful Widget

Definition

A Stateful Widget is a widget that can change its state during runtime. It allows dynamic updates in the UI when data changes or user interacts.

Key Characteristics:

  • Mutable (state can change)

  • Supports user interaction

  • Rebuilds UI using setState()

Example of Stateful Widget (Counter App)
import 'package:flutter/material.dart';

void main() {
  runApp(MyCounterApp());
}

class MyCounterApp extends StatefulWidget {
  @override
  _MyCounterAppState createState() => _MyCounterAppState();
}

class _MyCounterAppState extends State<MyCounterApp> {
  int counter = 0;

  void increment() {
    setState(() {
      counter++;
    });
  }

  void decrement() {
    setState(() {
      counter--;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Stateful Widget Example")),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text("Counter: $counter", style: TextStyle(fontSize: 24)),
              SizedBox(height: 20),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ElevatedButton(onPressed: increment, child: Text("+")),
                  SizedBox(width: 20),
                  ElevatedButton(onPressed: decrement, child: Text("-")),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

Real-Time Use Case

  • Shopping cart updates

  • Counter apps

  • Form inputs

  • Live dashboards

Example: Cart quantity increase/decrease in an e-commerce app

When to Use Stateless vs Stateful Widgets

Use Stateless Widget When:

  • Data is fixed

  • UI does not change

  • No user interaction

Examples:

  • Labels

  • Icons

  • Static pages

Use Stateful Widget When:

  • UI updates dynamically

  • User interaction is required

  • Data changes frequently

Examples:

  • Buttons

  • Forms

  • Toggles

  • Counters

Handling UI Updates with Stateful Widgets

Concept

In Flutter, UI updates occur when the state changes. The setState() method notifies Flutter to rebuild the widget with updated data.

Step-by-Step Working

  1. User performs an action (button click)

  2. State variable updates

  3. setState() is called

  4. UI rebuilds automatically

Example: Toggle Button
import 'package:flutter/material.dart';

void main() {
  runApp(ToggleExample());
}


class ToggleExample extends StatefulWidget {
  @override
  _ToggleExampleState createState() => _ToggleExampleState();
}

class _ToggleExampleState extends State<ToggleExample> {
  bool isOn = false;

  void toggleSwitch() {
    setState(() {
      isOn = !isOn;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Toggle Example")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              isOn ? "ON" : "OFF",
              style: TextStyle(fontSize: 24),
            ),
            ElevatedButton(
              onPressed: toggleSwitch,
              child: Text("Toggle"),
            ),
          ],
        ),
      ),
    );
  }
}

Real-Time Use Case

  • Dark/Light mode toggle

  • Notification ON/OFF

  • Smart home controls

State Management Using setState()

Definition

setState() is a method used in Stateful Widgets to update the UI whenever the state changes.

It tells Flutter:

“Rebuild this widget with updated values.”

Key Features of setState()

  • Triggers UI rebuild

  • Simple and easy to use

  • Best for small apps

  • Not suitable for large-scale apps (use Provider, Bloc, etc.)

Example: Like Button
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LikeButton(),
    );
  }
}
class LikeButton extends StatefulWidget {
  @override
  _LikeButtonState createState() => _LikeButtonState();
}

class _LikeButtonState extends State<LikeButton> {
  bool isLiked = false;

  void toggleLike() {
    setState(() {
      isLiked = !isLiked;
    });
  }

  @override
  Widget build(BuildContext context) {
    return IconButton(
      icon: Icon(
        isLiked ? Icons.favorite : Icons.favorite_border,
        color: Colors.red,
      ),
      onPressed: toggleLike,
    );
  }
}

Real-Time Use Case

  • Social media likes

  • Wishlist feature

  • Favorite items

Complete Real-Time Example – Simple Shopping Cart
import 'package:flutter/material.dart';

void main() {
  runApp(ShoppingApp());
}

class ShoppingApp extends StatefulWidget {
  @override
  _ShoppingAppState createState() => _ShoppingAppState();
}

class _ShoppingAppState extends State<ShoppingApp> {
  int quantity = 1;

  void increase() {
    setState(() {
      quantity++;
    });
  }

  void decrease() {
    setState(() {
      if (quantity > 1) quantity--;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Shopping Cart")),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text("Product Quantity: $quantity",
                  style: TextStyle(fontSize: 22)),
              SizedBox(height: 20),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ElevatedButton(onPressed: increase, child: Text("+")),
                  SizedBox(width: 20),
                  ElevatedButton(onPressed: decrease, child: Text("-")),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

Real-Time Application Scenario

This example is used in:

  • E-commerce apps

  • Inventory systems

  • Billing systems

  • Order management systems

Key Takeaways

  • Flutter UI is built using widgets

  • Stateless Widgets = Static UI

  • Stateful Widgets = Dynamic UI

  • setState() is used to update UI

  • Choose widget type based on behavior

  • Proper state management improves performance

Conclusion

Understanding Stateless and Stateful Widgets is essential for building interactive Flutter applications. While Stateless Widgets handle static content, Stateful Widgets allow dynamic updates using setState().

By mastering these concepts, developers can create real-world mobile applications such as dashboards, e-commerce apps, and interactive tools efficiently.

Subscribe for More

Subscribe to our blog and stay updated with the latest Flutter tutorials, real-world projects, and mobile app development guides to boost your development skills and career.

Write A Comment