StatelessWidget chỉ phụ thuộc vào tham số truyền vào (và các InheritedWidget nó đọc); StatefulWidget có thêm một object State sống lâu, giữ dữ liệu thay đổi được trong lúc widget còn trên cây.
StatelessWidget:build()chạy lại khi widget cha rebuild với tham số mới, hoặc khiInheritedWidgetnó phụ thuộc (Theme,MediaQuery) thay đổi.StatefulWidget: bản thân widget vẫn bất biến; dữ liệu đổi nằm trongState. GọisetState()để báo framework build lại.Statecó vòng đời riêng:initState(),didUpdateWidget(),dispose().
dart
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) => TextButton(
onPressed: () => setState(() => count++),
child: Text('$count'),
);
}Chọn StatelessWidget khi UI chỉ phụ thuộc input (nhãn, icon, card hiển thị dữ liệu); chọn StatefulWidget khi cần state cục bộ (toggle, tab đang chọn) hoặc giữ object phải dispose() như TextEditingController, AnimationController.
Lưu ý: "Stateless nhanh hơn" chỉ đúng một phần — lợi ích thật là code đơn giản và dễ đặt const. State dùng chung giữa nhiều màn nên đưa lên tầng state management (Provider, Riverpod, BLoC) thay vì nhồi vào StatefulWidget.