0
0
FlutterComparisonBeginner · 4 min read

Stateless vs Stateful Widget Flutter: Key Differences and Usage

In Flutter, a StatelessWidget is immutable and does not store any state, so it builds its UI once and never changes. A StatefulWidget can hold mutable state that can change during the widget's lifetime, allowing the UI to update dynamically.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of StatelessWidget and StatefulWidget in Flutter.

FactorStatelessWidgetStatefulWidget
StateNo mutable state, UI is staticHas mutable state, UI can update
LifecycleBuilt once, no state changesBuilt with a State object that can change
Use caseStatic UI, fixed contentDynamic UI, user interaction or data changes
PerformanceFaster, simplerSlightly heavier due to state management
ExampleText label, iconCheckbox, form input
⚖️

Key Differences

A StatelessWidget is a widget that never changes once it is built. It has no internal state to track, so its build() method is called only when the widget is first inserted into the widget tree or when its parent widget changes.

In contrast, a StatefulWidget is paired with a separate State object that holds mutable state. This state can change over time, and when it does, the widget rebuilds its UI by calling setState(). This allows the UI to react to user input, data updates, or animations.

Because StatefulWidget manages state, it has a more complex lifecycle with methods like initState(), dispose(), and didUpdateWidget(), which help manage resources and respond to changes.

⚖️

Code Comparison

This example shows a simple counter using a StatelessWidget. Notice it cannot update the counter because it has no state.

dart
import 'package:flutter/material.dart';

class CounterStateless extends StatelessWidget {
  final int count;

  CounterStateless({required this.count});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Stateless Counter')),
      body: Center(
        child: Text('Count: $count', style: TextStyle(fontSize: 24)),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Cannot update count here
        },
        child: Icon(Icons.add),
      ),
    );
  }
}
Output
A screen showing 'Count: 0' text and a floating button that does nothing when pressed.
↔️

StatefulWidget Equivalent

This example shows the same counter implemented as a StatefulWidget. It updates the count when the button is pressed.

dart
import 'package:flutter/material.dart';

class CounterStateful extends StatefulWidget {
  @override
  _CounterStatefulState createState() => _CounterStatefulState();
}

class _CounterStatefulState extends State<CounterStateful> {
  int count = 0;

  void _increment() {
    setState(() {
      count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Stateful Counter')),
      body: Center(
        child: Text('Count: $count', style: TextStyle(fontSize: 24)),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        child: Icon(Icons.add),
      ),
    );
  }
}
Output
A screen showing 'Count: 0' text and a floating button that increments the count each time it is pressed.
🎯

When to Use Which

Choose StatelessWidget when your UI does not need to change after it is built, such as static labels, icons, or simple layouts. This keeps your app fast and simple.

Choose StatefulWidget when your UI needs to update dynamically in response to user actions, data changes, or animations. Examples include forms, counters, toggles, and interactive lists.

Using the right widget type helps keep your app efficient and easier to maintain.

Key Takeaways

Use StatelessWidget for static UI that never changes.
Use StatefulWidget when UI needs to update dynamically.
StatefulWidget manages mutable state with a separate State object.
Stateless widgets are simpler and more performant.
Choosing the right widget type improves app clarity and performance.