🔖 หมวดบทเรียน: การจัดการ State ที่ซับซ้อนในแอประดับกลางถึงใหญ่
📌 เหมาะสำหรับ: แอปที่มีหลายหน้าหรือหลายฟีเจอร์ที่ต้องแชร์/แยก State กันอย่างเป็นระบบ
🎯 เป้าหมาย: เข้าใจการจัดการ State หลายระดับ (multi-level) ด้วยโครงสร้างที่ maintain ง่าย
🧭 เกริ่นนำ
ในการพัฒนาแอปขนาดกลางถึงใหญ่ มักมีหลายหน้า หลาย component ที่ต้องใช้ข้อมูลร่วมกัน หรือแยกเฉพาะบางส่วน การจัดการ State ที่ซ้อนกันหลายระดับจึงเป็นเรื่องสำคัญ ในบทนี้เราจะเปรียบเทียบและยกตัวอย่างการใช้ทั้ง Nested Provider
, ScopedModel
, และ Riverpod
🧱 ตัวอย่าง Nested Provider
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => AuthModel()),
ChangeNotifierProvider(create: (_) => CartModel()),
],
child: MyApp(),
);
เรียกใช้งาน:
final auth = Provider.of<AuthModel>(context);
final cart = Provider.of<CartModel>(context);
🌱 ตัวอย่าง ScopedModel (Legacy)
ScopedModel<AuthModel>(
model: AuthModel(),
child: ScopedModelDescendant<AuthModel>(
builder: (context, child, model) => Text(model.username),
),
);
🔍 ข้อสังเกต: ScopedModel ถูกแทนที่ด้วย Provider / Riverpod แล้ว จึงไม่แนะนำให้ใช้ในโปรเจกต์ใหม่
🧬 ตัวอย่าง Riverpod (Structured State Sharing)
final authProvider = Provider((ref) => AuthModel());
final cartProvider = ChangeNotifierProvider((ref) => CartModel());
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final auth = ref.watch(authProvider);
final cart = ref.watch(cartProvider);
return Column(
children: [
Text(auth.username),
Text('จำนวนสินค้า: \${cart.total}'),
],
);
}
}
✅ สรุป
- Nested Provider เหมาะกับโปรเจกต์ขนาดกลางที่ยังไม่ซับซ้อนมาก
- Riverpod ยืดหยุ่นและปลอดภัยกว่า เหมาะกับโปรเจกต์ระยะยาว
- ScopedModel เป็นแนวทางเก่า ไม่ควรใช้ในโปรเจกต์ใหม่
ในบทถัดไปเราจะไปดูเรื่อง การใช้งาน Custom Hooks กับ Riverpod เพื่อให้การจัดการ State ง่ายและยืดหยุ่นยิ่งขึ้น