บทความ
วิธีใช้งาน Provider กับ State Management
ในการใช้งาน Provider และ Dio ใน Flutter สามารถสรุปได้ดังนี้
- Provider เป็น State Management Library ที่ช่วยในการจัดการ State ในแอปพลิเคชัน Flutter ได้ดีมาก โดยสามารถใช้งานได้หลายแบบ เช่น ChangeNotifierProvider, StateNotifierProvider และ ProxyProvider
- Dio เป็น Library ที่ช่วยในการเรียกใช้งาน API ในแอปพลิเคชัน Flutter ได้สะดวกมาก และสามารถทำงานร่วมกับ Provider ได้ง่าย
- เราสามารถใช้ Provider ร่วมกับ Dio ในการจัดการ State และเรียกใช้งาน API ในแอปพลิเคชัน Flutter ได้อย่างมีประสิทธิภาพ
- การใช้งาน Provider และ Dio ใน Flutter ควรใช้งานร่วมกันเพื่อเพิ่มประสิทธิภาพในการจัดการ State และเรียกใช้งาน API ในแอปพลิเคชัน
Provider ใน Flutter คือ library ที่ช่วยในการจัดการ State ของแอปพลิเคชันด้วยวิธี Dependency Injection ซึ่งเป็นการเชื่อมต่อการติดต่อกันระหว่างคลาสหรือ Widget ในแอปพลิเคชัน ทำให้เราสามารถเข้าถึง State และข้อมูลต่างๆ ได้ง่ายขึ้น และลดความซับซ้อนของโค้ดในการจัดการ State และการส่งข้อมูลระหว่าง Widget ได้มากยิ่งขึ้น
Provider มีหลายวิธีการใช้งานให้เลือกตามความต้องการของโปรเจ็กต์ เช่น Provider.of(), Consumer, Selector, ChangeNotifierProvider, และ StreamProvider โดยการใช้งาน Provider จะช่วยให้การจัดการ State ในแอปพลิเคชัน Flutter มีประสิทธิภาพและเป็นระเบียบ และช่วยให้เราสามารถส่งข้อมูลระหว่าง Widget ได้ง่ายและได้รับการอัพเดทในเวลาเดียวกัน
การใช้งาน Provider จะช่วยให้การจัดการ State ในแอปพลิเคชัน Flutter มีประสิทธิภาพและเป็นระเบียบ และช่วยให้เราสามารถส่งข้อมูลระหว่าง Widget ได้ง่ายและได้รับการอัพเดทในเวลาเดียวกัน
ตัวอย่างการใช้งาน Provider และ Dio ใน Flutter ได้แก่
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:dio/dio.dart';
void main() {
runApp(MyApp());
}
class Post {
final int id;
final String title;
final String body;
Post({this.id, this.title, this.body});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
id: json['id'],
title: json['title'],
body: json['body'],
);
}
}
class PostService {
Dio dio = Dio();
Future<List<Post>> getPosts() async {
final response = await dio.get('https://jsonplaceholder.typicode.com/posts');
if (response.statusCode == 200) {
final data = response.data as List;
final posts = data.map((postJson) => Post.fromJson(postJson)).toList();
return posts;
} else {
throw Exception('Failed to load posts');
}
}
}
class PostModel extends ChangeNotifier {
List<Post> _posts;
List<Post> get posts => _posts;
set posts(List<Post> posts) {
_posts = posts;
notifyListeners();
}
Future<void> fetchPosts(PostService postService) async {
try {
final posts = await postService.getPosts();
_posts = posts;
} catch (e) {
throw Exception('Failed to load posts: $e');
}
}
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<PostModel>(
create: (context) => PostModel(),
),
ProxyProvider<Dio, PostService>(
create: (_) => PostService(),
update: (_, dio, postService) => postService..dio = dio,
),
],
child: MaterialApp(
title: 'Flutter Provider and Dio',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Provider and Dio'),
),
body: Center(
child: Consumer<PostModel>(
builder: (context, postModel, _) {
return postModel.posts == null
? CircularProgressIndicator()
: ListView.builder(
itemCount: postModel.posts.length,
itemBuilder: (context, index) => ListTile(
title: Text(postModel.posts[index].title),
subtitle: Text(postModel.posts[index].body),
),
);
},
),
),
),
),
);
}
}
ในตัวอย่างนี้เราใช้ MultiProvider เพื่อใช้งาน PostModel และ PostService โดย ProxyProvider จะช่วยในการสร้าง PostService และ ChangeNotifierProvider จะช่วยในการจัดการ State ของ PostModel
เราสามารถดึงค่า State จาก PostModel ผ่าน Consumer และเรียกใช้งาน API ผ่าน PostService ที่ได้รับ Dio จาก ProxyProvider
ในตัวอย่างนี้เมื่อเราเปิดแอปพลิเคชันขึ้นมา จะมีการเรียกใช้งาน API ผ่าน PostService และโหลดข้อมูลโพสต์มาแสดงผลบนหน้าจอ โดยโชว์ CircularProgressIndicator เมื่อกำลังโหลด และโชว์ ListView.builder เมื่อโหลดเสร็จสมบูรณ์แล้ว
เมื่อมีการเปลี่ยนแปลง State ของ PostModel โดยการโหลดข้อมูลโพสต์ใหม่ จะมีการ rebuild Widget ผ่าน Consumer ที่อยู่ภายใน ListView.builder โดยข้อมูลโพสต์ใหม่ที่โหลดจะถูกแสดงผลให้ผู้ใช้งานเห็นได้เลย
นอกจากนี้ยังมีวิธีการใช้งาน MultiProvider ในการสร้าง Provider หลายๆ ตัวพร้อมๆ กัน เพื่อใช้งานในการจัดการ State หลายๆ อย่าง ตัวอย่างเช่นการใช้งาน MultiProvider ในการสร้าง ChangeNotifierProvider, StateNotifierProvider และ ProxyProvider พร้อมๆ กัน เพื่อใช้งานในการจัดการ State และเรียกใช้งาน API ในแอปพลิเคชัน Flutter ได้ดังตัวอย่างนี้
MultiProvider(
providers: [
ProxyProvider<Dio, PostService>(
create: (_) => PostService(),
update: (_, dio, postService) => postService..dio = dio,
),
StateNotifierProvider<PostProvider, AsyncValue<List<Post>>>(
create: (context) => PostProvider(context.read<PostService>()),
),
ChangeNotifierProvider<PostModel>(
create: (context) => PostModel(),
),
],
child: MaterialApp(
title: 'Flutter Provider and Dio',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Provider and Dio'),
),
body: Center(
child: Consumer<PostModel>(
builder: (context, postModel, _) {
return postModel.posts == null
? CircularProgressIndicator()
: ListView.builder(
itemCount: postModel.posts.length,
itemBuilder: (context, index) => ListTile(
title: Text(postModel.posts[index].title),
subtitle: Text(postModel.posts[index].body),
),
);
},
),
),
),
),
);
ในตัวอย่างนี้เราใช้งาน MultiProvider เพื่อใช้งาน PostProvider, PostModel และ Dio พร้อมๆ กัน โดย ProxyProvider จะช่วยในการสร้าง PostService และ StateNotifierProvider จะช่วยในการจัดการ State ของ Provider และ ChangeNotifierProvider จะช่วยในการจัดการ State ของ PostModel
เราสามารถดึงค่า State จาก PostProvider ผ่าน watch และ rebuild Widget ตามสถานะของ AsyncValue แต่ละส่วน เช่น loading state, error state, และ data state และเรียกใช้งาน PostModel ผ่าน Consumer ที่ rebuild Widget เมื่อ State ของ PostModel เปลี่ยนแปลง
นอกจากนี้ยังมีวิธีการใช้งานต่างๆ ที่เราสามารถปรับใช้ได้ตามความต้องการ ตัวอย่างเช่น
- การใช้งาน ChangeNotifierProvider.value
ChangeNotifierProvider.value(
value: PostModel(),
),
- การใช้งาน Consumer2 หรือ Consumer3 เพื่อใช้งานหลาย State พร้อมกัน
Consumer2<PostModel, UserModel>(
builder: (context, postModel, userModel, _) {
// use postModel and userModel here
return Container();
},
),
- การใช้งาน Selector เพื่อเลือกเฉพาะ State บางส่วนที่เราต้องการใช้งาน
Selector<PostModel, List<Post>>(
selector: (context, postModel) => postModel.posts,
builder: (context, posts, _) {
// use only posts here
return Container();
},
),
- การใช้งาน FutureProvider เพื่อสร้าง Provider จาก Future
FutureProvider<List<Post>>(
create: (_) => PostService().getPosts(),
initialData: [],
child: MyApp(),
),
โดยการใช้งาน Provider และ Dio ใน Flutter จะช่วยในการจัดการ State และการเรียกใช้งาน API ในแอปพลิเคชันได้อย่างมีประสิทธิภาพ และมีหลายวิธีการใช้งานให้เลือกใช้ตามความต้องการของแต่ละโปรเจ็กต์ จึงเป็นสิ่งสำคัญที่ต้องศึกษาในการพัฒนาแอปพลิเคชัน Flutter
นอกจาก Provider และ Dio ยังมี library อื่นๆ ที่ช่วยในการจัดการ State และการเรียกใช้งาน API ใน Flutter ได้ดีเช่นกัน ตัวอย่างเช่น
-
GetX: library ที่มีความสามารถในการจัดการ State, Dependency Injection และการเรียกใช้งาน API ที่มีประสิทธิภาพสูง และสามารถทำงานได้เร็วกว่า Provider และ Dio ในบางกรณี
-
Bloc: library ที่ใช้สำหรับจัดการ State โดยใช้วิธีการ Flux และมีความสามารถในการจัดการ State ซับซ้อนได้ดี และช่วยในการทำ TDD (Test Driven Development) ได้ง่ายขึ้น
-
Riverpod: library ที่เป็น alternative ของ Provider และมีการพัฒนาอย่างต่อเนื่องจาก Provider โดยมีความสามารถในการเขียนแบบ Functional Programming และมี API ที่ใช้งานง่าย
โดยเราสามารถเลือกใช้ library ตามความต้องการของโปรเจ็กต์ และการพัฒนาแอปพลิเคชันเพื่อให้ได้ประสิทธิภาพและความสะดวกในการพัฒนาที่ต้องการ
ในบทสนทนานี้เราได้เรียนรู้เกี่ยวกับ Flutter Provider และ Dio ที่เป็น library ที่ช่วยในการจัดการ State และการเรียกใช้งาน API ในแอปพลิเคชัน Flutter โดย Provider ช่วยในการจัดการ State ของแอปพลิเคชันด้วยวิธี Dependency Injection และมีหลายวิธีการใช้งานให้เลือกตามความต้องการ ส่วน Dio เป็น library ที่ช่วยในการเรียกใช้งาน API โดยมีการจัดการ Request และ Response อย่างมีประสิทธิภาพ
นอกจาก Flutter Provider และ Dio ยังมี library อื่นๆ ที่ช่วยในการจัดการ State และการเรียกใช้งาน API ใน Flutter ได้ดีเช่นกัน เช่น GetX และ Bloc ซึ่งเป็น library ที่มีความสามารถที่แตกต่างกันไป และสามารถเลือกใช้ตามความต้องการของโปรเจ็กต์ได้
การใช้งาน library เหล่านี้ไม่ได้หมายความว่าควรใช้ library อะไรก็ตามเพื่อเป็นการแทนที่ Flutter Provider และ Dio แต่อย่างใด แต่เป็นวิธีที่ช่วยให้การจัดการ State และการเรียกใช้งาน API ในแอปพลิเคชัน Flutter ได้ง่ายขึ้น และทำให้การพัฒนาแอปพลิเคชันเป็นไปอย่างมีประสิทธิภาพสูงขึ้น
หนังสือพัฒนาตัวเอง
จุดเริ่มต้นที่ชัดเจน