What's the difference between a `StatelessWidget` and a `StatefulWidget`, and when should you use each one?
Show answer — try answering out loud first
A StatelessWidget has no internal state that changes: it's drawn once with the information it receives and doesn't redraw itself. A StatefulWidget holds mutable state that can change during the widget's lifetime; when that state changes (with setState), Flutter rebuilds it. Use stateful only when the widget needs to change on its own.
StatelessWidget: pure description. Everything it needs arrives through its constructor (its parameters). If that data doesn't change, the widget doesn't change. Examples: an icon, a text label, a button that just displays something.StatefulWidget: has an associatedStateclass where information that can change lives: a counter, whether a switch is on, the text of a field. When you callsetState(), Flutter runsbuildagain and updates the UI.
Rule of thumb: always start with StatelessWidget. Only move to StatefulWidget when the widget needs to remember something that changes over time and that it controls itself.
import 'package:flutter/material.dart';
// Stateless: just shows what it receives
class Greeting extends StatelessWidget {
final String name;
const Greeting({super.key, required this.name});
@override
Widget build(BuildContext context) {
return Text("Hello, $name");
}
}
// Stateful: holds a counter that changes
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0; // mutable state
void _increment() {
setState(() {
_count++; // change the state and request a rebuild
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("Count: $_count"),
ElevatedButton(onPressed: _increment, child: const Text("+1")),
],
);
}
}
Using StatefulWidget for everything "just in case." A stateful widget is heavier and more prone to bugs (forgetting setState, not cleaning up resources in dispose). If the data only comes from outside and doesn't change inside the widget, a StatelessWidget is simpler and more efficient. Another mistake: modifying a state variable without wrapping it in setState, which means the UI won't update.
"A
StatelessWidgethas no internal state that changes: it's drawn with what it receives through the constructor and doesn't redraw itself. AStatefulWidgethas aStateclass with mutable data, and when I callsetStateFlutter rebuilds the widget to reflect the change. My rule is to start with stateless and only use stateful when the widget needs to remember something that changes over time, like a counter or a form."
If you change a state variable but the UI doesn't update, what's the most likely cause?
See answer
That you modified the variable outside of setState(). Changing _count++ directly updates the value in memory, but it doesn't tell Flutter it needs to rebuild. You have to wrap the change: setState(() { _count++; });. (In a StatelessWidget there's simply no setState because it isn't meant to change on its own.)