State Management
การจัดการข้อมูลที่เปลี่ยนแปลงได้ (state) ใน Flutter app — ตั้งแต่วิธีง่ายๆ จนถึง package เต็มรูปแบบ
ระดับของ State Management
1. Local State — setState()
state อยู่ใน widget ตัวเดียว ไม่ต้อง share:
class _CounterState extends State<Counter> {
var count = 0;
void increment() {
setState(() { count++; }); // บอก Flutter ให้ rebuild
}
}เหมาะกับ: UI state ง่ายๆ เช่น toggle, counter, form input
2. Lifting State Up — ย้าย state ขึ้น parent
เมื่อ 2+ widget ต้อง share state → ย้าย state ไปไว้ที่ parent widget ร่วม:
// Parent เก็บ state + ส่ง function ลงไป
class _QuizState extends State<Quiz> {
var activeScreen = 'start-screen';
void switchScreen() {
setState(() { activeScreen = 'questions-screen'; });
}
@override
Widget build(BuildContext context) {
return activeScreen == 'start-screen'
? StartScreen(switchScreen) // ส่ง function ลงไป
: QuestionsScreen(chooseAnswer);
}
}เหมาะกับ: 2-3 widget share state, แอปขนาดเล็ก
3. Riverpod — State Management Package
เมื่อแอปซับซ้อน การส่ง state ผ่าน constructor หลายชั้น (prop drilling) ยุ่งยากเกินไป:
// สร้าง Provider กลาง
final favoritesProvider = StateNotifierProvider<FavNotifier, List<Meal>>(
(ref) => FavNotifier(),
);
// widget ไหนก็เข้าถึงได้ตรงๆ
class MyScreen extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final favs = ref.watch(favoritesProvider);
return ListView(...);
}
}เหมาะกับ: แอปขนาดกลาง-ใหญ่, หลาย widget share state
เลือกแบบไหนดี
state ใช้ใน widget เดียว?
├── ใช่ → setState() (local state)
└── ไม่ → share กี่ widget?
├── 2-3 ตัว, ใกล้กัน → Lifting State Up
└── หลายตัว, กระจาย → Riverpod
Conditional Rendering — แสดง UI ตามเงื่อนไข
pattern ที่ใช้บ่อยร่วมกับ state management:
// Ternary expression (แนะนำ)
child: isStartScreen
? StartScreen(switchScreen)
: QuestionsScreen(onSelectAnswer: chooseAnswer),
// if-else ใน build()
Widget screenWidget;
if (activeScreen == 'start') {
screenWidget = StartScreen(switchScreen);
} else if (activeScreen == 'questions') {
screenWidget = QuestionsScreen(chooseAnswer);
} else {
screenWidget = ResultsScreen(restartQuiz);
}Key Points
- เริ่มจาก
setState()→ ย้ายไป Lifting State Up → ย้ายไป Riverpod เมื่อซับซ้อนขึ้น setState()บอก Flutter ให้ rebuild — ถ้าลืมใส่ UI จะไม่อัปเดต- Lifting State Up = ย้าย state ขึ้น parent + ส่ง function ลงมา
- Riverpod แก้ปัญหา prop drilling — widget เข้าถึง state ได้ตรงจากไหนก็ได้
Related
- Flutter — framework ที่ต้องจัดการ state
- Riverpod — state management package หลักที่คอร์สสอน
- Lifting State Up — pattern พื้นฐาน
- Widgets — StatefulWidget, ConsumerWidget
- Three Trees — เข้าใจว่า setState ทำงานข้างในยังไง