Widgets: Stateless vs Stateful

June 02, 2026 1 min read

Flutter has two main widget types. StatelessWidget never changes after it's built; StatefulWidget can rebuild itself when its data changes.

Stateless

class Greeting extends StatelessWidget {
  final String name;
  const Greeting(this.name, {super.key});
  @override
  Widget build(BuildContext context) => Text('Hello, $name');
}

Stateful

class Counter extends StatefulWidget {
  const Counter({super.key});
  @override
  State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
  int count = 0;
  @override
  Widget build(BuildContext context) => ElevatedButton(
    onPressed: () => setState(() => count++),
    child: Text('Count: $count'),
  );
}

setState() tells Flutter to rebuild the widget with the new data.

Common mistake: Don't do heavy work inside build() — it can run many times. Keep build() fast and pure.

Summary

Use StatelessWidget for fixed UI and StatefulWidget + setState for UI that changes over time.