Lifting State Up
Pattern พื้นฐานใน Flutter สำหรับ share state ระหว่าง widget — ย้าย state ขึ้นไปยัง parent widget ที่เป็น ancestor ร่วมของ widgets ที่ต้องใช้ state นั้น
ปัญหา
StartScreen กับ QuestionsScreen ต้อง share state (activeScreen) แต่เป็น sibling กัน → ส่ง state ตรงๆ ระหว่างกันไม่ได้
Quiz (parent)
├── StartScreen ← ต้องรู้ว่าเมื่อไหร่ควรเปลี่ยนหน้า
└── QuestionsScreen ← ต้องรู้ว่าเมื่อไหร่ควรแสดง
วิธีแก้
ย้าย state + logic ไปไว้ที่ parent (Quiz) แล้วส่ง function ลงไปให้ children:
class _QuizState extends State<Quiz> {
var activeScreen = 'start-screen';
List<String> selectedAnswers = [];
void switchScreen() {
setState(() { activeScreen = 'questions-screen'; });
}
void chooseAnswer(String answer) {
selectedAnswers.add(answer);
if (selectedAnswers.length == questions.length) {
setState(() { activeScreen = 'results-screen'; });
}
}
@override
Widget build(BuildContext context) {
return activeScreen == 'start-screen'
? StartScreen(switchScreen) // ส่ง function ลงไป
: QuestionsScreen(onSelectAnswer: chooseAnswer);
}
}// StartScreen รับ function จาก parent
class StartScreen extends StatelessWidget {
const StartScreen(this.startQuiz, {super.key});
final void Function() startQuiz;
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: startQuiz, // ← เรียก function ของ parent
child: const Text('Start Quiz'),
);
}
}หลักการ
- หา ancestor ร่วม ของ widgets ที่ต้อง share state
- ย้าย state ไปไว้ที่ ancestor นั้น (ทำเป็น StatefulWidget)
- ส่ง data ลงไป ผ่าน constructor (ค่าที่อ่าน)
- ส่ง function ลงไป ผ่าน constructor (ค่าที่เปลี่ยน)
ข้อจำกัด
เมื่อ widget tree ลึกหลายชั้น → ต้องส่ง state ผ่าน constructor ทีละชั้น (prop drilling):
Parent (เก็บ state)
→ Child A (ส่งต่อ)
→ Child B (ส่งต่อ)
→ Child C (ใช้จริง) ← ต้องผ่าน 3 ชั้น!
แก้ด้วย: Riverpod หรือ state management package อื่น
Key Points
- ย้าย state ขึ้น parent ที่เป็น ancestor ร่วม → ส่ง function ลงมา
- Pattern นี้ใช้ได้ดีกับแอปขนาดเล็ก (2-3 widget share state)
- เมื่อ tree ลึก → prop drilling ยุ่งยาก → ย้ายไปใช้ Riverpod
Related
- State Management — ภาพรวม state management ทุกระดับ
- Riverpod — ทางเลือกเมื่อ lifting state up ไม่เพียงพอ
- Flutter — framework ที่ใช้ pattern นี้
- Widgets — StatefulWidget เก็บ state ที่ถูก lift ขึ้นมา