Ref qaydaları: watch, read, listen, invalidate
Rəsmi sənəd Ref-i belə təsvir edir: provider-lərlə əlaqə saxlamağın əsas yolu — Flutter-in BuildContext-inə bənzər rol.
Dörd əsas metod və onların yeri:
- `ref.watch` — deklarativ dinləmə. Sənəd birbaşa yazır: bu, provider-ləri dinləməyin ən çox yayılmış üsuludur və ilk seçiminiz olmalıdır. Yeri: widget-in
buildmetodu və provider-in gövdəsi. - `ref.read` — abunə olmadan cari dəyəri oxumaq. Yeri: yalnız istifadəçi hərəkətləri — düymə basılışı kimi callback-lər.
- `ref.listen` — dəyişikliyə yan effekt ilə cavab vermək: dialoq göstərmək, naviqasiya, log.
buildiçində təhlükəsizdir;build-dən kənarda (initState) isəref.listenManualistifadə olunur. - `ref.onDispose` — provider söküləndə təmizləmə (subscription, timer, controller).
State-i sıfırlamaq üçün: ref.invalidate(provider) state-i atır və növbəti oxunuşda yenidən hesablayır; ref.refresh(provider) isə sənədin ifadəsi ilə invalidate + read-in sintaktik şəkəridir.
Sənədin xüsusi xəbərdarlığı: `ref.read`-i `ref.watch`-dan yayınmaq üçün "optimizasiya" vasitəsi kimi istifadə etməyin — bu, kodunuzu daha kövrək edir. Bu, müsahibədə çox verilən "performans üçün read istifadə etmək olar?" sualının rəsmi cavabıdır: yox, çünki read dəyişikliyi görmür və UI səssizcə köhnə dəyərlə qalır.
class TodoPage extends ConsumerWidget {
const TodoPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// watch: deklarativ oxunuş, dəyişiklikdə rebuild.
final todos = ref.watch(todosProvider);
// listen: yan effekt — build içində təhlükəsizdir.
ref.listen(todosProvider, (previous, next) {
if (next.hasError) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Yükləmə alınmadı')),
);
}
});
return Scaffold(
body: switch (todos) {
AsyncValue(:final value?) => TodoList(items: value),
AsyncValue(:final error?) => ErrorView(message: '$error'),
_ => const Center(child: CircularProgressIndicator()),
},
floatingActionButton: FloatingActionButton(
// read: istifadəçi hərəkəti, abunəlik lazım deyil.
onPressed: () => ref.read(todosProvider.notifier).add('Yeni tapşırıq'),
child: const Icon(Icons.add),
),
);
}
}
// Provider daxilində: watch → asılılıq, onDispose → təmizləmə.
final chatProvider = StreamProvider<List<Message>>((ref) {
final socket = ref.watch(socketProvider);
final controller = socket.subscribe('chat');
ref.onDispose(controller.close);
return controller.stream;
});Hər metod öz yerində.
| Metod | Abunəlik | İcazəli yer | Tipik istifadə |
|---|---|---|---|
| `ref.watch` | Var — dəyişiklikdə rebuild/yenidən hesablama | `build`, provider gövdəsi | Dəyəri göstərmək, asılılıq qurmaq |
| `ref.read` | Yox | Callback-lər (`onPressed`, `onTap`) | Notifier-in metodunu çağırmaq |
| `ref.listen` | Var, lakin rebuild etmir | `build` (kənarda `listenManual`) | SnackBar, dialoq, naviqasiya, log |
| `ref.invalidate` / `ref.refresh` | — | Callback-lər, notifier metodları | Yenidən yükləmə, pull-to-refresh |
Rəsmi DO/DON'T qaydaları (müsahibədə birbaşa sitat gətirməyə dəyər):
- Provider-i widget-dən inisiallaşdırmaqdan çəkinin — provider özünü özü inisiallaşdırmalıdır; əks halda race condition riski var.
- Ephemeral state (form state, seçilmiş element, controller) üçün provider istifadə etməkdən çəkinin.
- Provider-in inisiallaşdırılması zamanı yan effekt (məsələn form göndərmək) etməyin — provider oxunuş əməliyyatını təmsil edir.
ref.watch/read/listen-i statik məlum provider-lərlə işlədin — provider-i parametr kimi ötürmək statik analizi və lint-i işləməz edir.- Provider-ləri yalnız top-level
finaldəyişən kimi yaradın.
📚 Mənbələr və sənədlər
- Ref: watch, read, listenrəsmiriverpod.dev
Hər metodun rəsmi təyinatı və read-i optimizasiya kimi işlətməmək xəbərdarlığı.
- DO / DON'Trəsmiriverpod.dev
Yuxarıdaki qaydaların hamısının mənbəyi.
- Pull-to-refreshrəsmiriverpod.dev
ref.refresh(provider.future) və RefreshIndicator nümunəsi.
- Sorğunun ləğvi (cancel)rəsmiriverpod.dev