Tipik səhvlər və xəta mesajları
Provider ilə bağlı xətaların böyük hissəsi eyni üç kökdən gəlir: səhv `context`, səhv ömür, səhv oxunuş növü. Xəta mesajını tanımaq müsahibədə də praktikada da vaxt qazandırır.
| Xəta | Səbəb | Həll |
|---|---|---|
| `ProviderNotFoundException` — "Could not find the correct Provider<T> above this widget" | Oxunuş elə `context`-lə aparılır ki, provider ondan yuxarıda deyil (məsələn provider-in yaradıldığı widget-in öz `context`-i, ya da dialoq/route kontekstindən kənar) | Provider-i daha yuxarı qaldırmaq, ya da alt ağac üçün `Builder`/ayrı widget ilə yeni `context` almaq |
| "A ChangeNotifier was used after being disposed" | Mövcud obyekt `create`-ə verilib və provider onu sökmüş; ya da async əməliyyat notifier söküldükdən sonra qayıdıb `notifyListeners()` çağırır | `.value` istifadə etmək; async-dan sonra obyektin hələ yaşadığını yoxlamaq |
| "setState() or markNeedsBuild() called during build" | `build` gedişində `notifyListeners()` çağırılır — məsələn `build` içindən metod işə salınır | Yükləməni `initState`/`didChangeDependencies`-ə köçürmək, ya da bir frame gecikdirmək |
| UI heç yenilənmir | `build`-də `read` istifadə olunub; ya `notifyListeners()` çağırılmayıb; ya `select` mutable dəyər qaytarır | `watch`/`Consumer`-ə keçmək; immutable dəyər seçmək |
Provider sənədində faydalı bir detal var: tipi nullable yazsanız (context.watch<Model?>()), provider ağacda yoxdursa exception atılmır, null qaytarılır. Bu, opsional provider-lər üçün nəzərdə tutulub — lakin onu ProviderNotFoundException-ı gizlətmək üçün istifadə etmək bug-ı səssiz edir. Müsahibədə bu nüansı bilmək diqqət göstərir.
dart
// ❌ showDialog-un builder-i başqa (Navigator-un overlay) context-i alır;
// provider bu context-dən yuxarıda olmaya bilər → ProviderNotFoundException.
void _confirm(BuildContext context) {
showDialog(
context: context,
builder: (dialogContext) => AlertDialog(
content: Text(dialogContext.watch<CartModel>().summary),
),
);
}
// ✅ Variant 1: dəyəri dialoq açılmadan əvvəl oxumaq.
void _confirm(BuildContext context) {
final summary = context.read<CartModel>().summary;
showDialog(
context: context,
builder: (_) => AlertDialog(content: Text(summary)),
);
}
// ✅ Variant 2: mövcud modeli dialoq ağacına .value ilə ötürmək.
void _confirm(BuildContext context) {
final cart = context.read<CartModel>();
showDialog(
context: context,
builder: (_) => ChangeNotifierProvider.value(
value: cart,
child: const CartDialog(),
),
);
}Ən çox rastlanan hal: dialoqda provider tapılmır.
📚 Mənbələr və sənədlər
- package:provider — xətalar və FAQrəsmipub.dev
ProviderNotFoundException, nullable tip fəndi və DO/DON'T siyahısı README-də.
- BuildContext və dependency qurmaqrəsmiapi.flutter.dev
Uyğun widget tapılmadıqda null qaytarılması və initState qadağası burada yazılıb.
- ChangeNotifier: disposerəsmiapi.flutter.dev