Riverpod: Notifier
Thuộc phần Quản lý trạng thái trong hành trình Flutter của Coddy. Bài học 19 trên 27.
StateProvider phù hợp với một số. Khi trạng thái đi kèm các quy tắc, chẳng hạn như một danh sách có phương thức thêm và xóa phần tử, hãy viết một Notifier: một lớp lưu giữ trạng thái và các phương thức thay đổi trạng thái đó.
class GuestList extends Notifier<List<String>> {
@override
List<String> build() => [];
void add(String name) {
state = [...state, name];
}
}
final guestsProvider =
NotifierProvider<GuestList, List<String>>(GuestList.new);build trả về trạng thái ban đầu, một danh sách trống. Bên trong lớp, state là giá trị hiện tại. GuestList.new là hàm khởi tạo của lớp, được truyền cho provider để nó có thể tạo notifier.
Quy tắc quan trọng: gán giá trị mới cho state, không bao giờ thay đổi giá trị cũ. Riverpod chỉ thông báo cho các widget khi state được gán một đối tượng khác. state.add(name) thay đổi danh sách ngay tại chỗ, nên state vẫn là cùng một danh sách và không ai nhận được thông báo. [...state, name] tạo một danh sách mới: ba dấu chấm trải tất cả tên cũ vào danh sách, rồi thêm tên mới vào cuối.
Một widget gọi phương thức thông qua notifier: ref.read(guestsProvider.notifier).add('Ada'). Trang này dùng ConsumerStatefulWidget, loại widget có trạng thái, vì nó cũng lưu một bộ điều khiển văn bản. State của nó có ref làm thuộc tính.
Thử thách
KhóDanh sách khách hiển thị tên trong guestsProvider, nhưng Add chỉ xóa nội dung trường nhập.
- Thêm phương thức
add(String name)vàoGuestListđể đặtstatethành một danh sách mới, với tên ở cuối danh sách. - Cho
Addgọi phương thức đó với nội dung trong trường nhập, trước khi xóa nội dung trường.
Tự làm thử
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class GuestList extends Notifier<List<String>> {
@override
List<String> build() => [];
}
final guestsProvider = NotifierProvider<GuestList, List<String>>(GuestList.new);
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: PartyPage(),
);
}
}
class PartyPage extends ConsumerStatefulWidget {
const PartyPage({super.key});
@override
ConsumerState<PartyPage> createState() => _PartyPageState();
}
class _PartyPageState extends ConsumerState<PartyPage> {
final controller = TextEditingController();
@override
Widget build(BuildContext context) {
final guests = ref.watch(guestsProvider);
return Scaffold(
appBar: AppBar(title: Text('Guests: ${guests.length}')),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Expanded(
child: TextField(
controller: controller,
decoration: const InputDecoration(labelText: 'Guest name'),
),
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: () {
controller.clear();
},
child: const Text('Add'),
),
],
),
),
Expanded(
child: ListView(
children: [
for (final name in guests) ListTile(leading: const Icon(Icons.person), title: Text(name)),
],
),
),
],
),
);
}
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Quản lý trạng thái
Tự luyện tập: Trình biên dịch Flutter online