Sparround

Riverpod 2 → 3 keçidi

Riverpod 3 mövcud kodun böyük hissəsini saxlayır, lakin bir sıra vacib dəyişikliklər gətirir. Sənədin "nə yenidir" səhifəsindən əsas bəndlər:

Köhnə API-lar ayrı import-a köçürüldü. StateProvider, StateNotifierProviderChangeNotifierProvider istifadəni azaltmaq üçün package:riverpod/legacy.dart-a keçirildi. Onlar geriyə uyğunluq üçün işləməyə davam edir.

Breaking dəyişikliklər:

  • Ref və notifier-lər söküldükdən sonra müraciət edildikdə xəta atır.
  • Provider-dən çıxan exception-lar daha yaxşı diaqnostika üçün ProviderException içərisinə bükülür.
  • AsyncValue sealed oldu; valueOrNull value adına dəyişdirildi.
  • Bütün updateShouldNotify implementasiyaları artıq == müqayisəsindən istifadə edir.
  • AutoDisposeNotifierFamilyNotifier bir Notifier sinfində birləşdirildi.
  • Vahid Ref: FutureProviderRef kimi provider-ə xas tiplər aradan qaldırıldı.

Yeni imkanlar: avtomatik retry (eksponensial gecikmə ilə), Ref.mounted, pause/resume (görünməyən widget-lər üçün avtomatik dayandırma), təcrübi Mutation mexanizmi və təcrübi offline persistence (riverpod_sqflite kimi implementasiyalarla).

DəyişiklikPraktik təsiri
Legacy provider-lər ayrı import-daKod sınmır, lakin import əlavə etmək lazım gəlir — bu, tədricən köçürmə üçün siqnaldır
`AsyncValue` sealed oldu`switch` üzərində pattern matching tam yoxlanılır; `valueOrNull` → `value` adı yenilənməlidir
Söküldükdən sonra müraciətdə xətaƏvvəl səssiz keçən səhvlər indi görünür — testlərdə yeni uğursuzluqlar çıxa bilər
`ProviderException` bükməsiXəta idarəsində tipə görə yoxlama aparan kod yenidən nəzərdən keçirilməlidir
Avtomatik retryŞəbəkə xətalarında UI-ın davranışı dəyişir; xəta ekranı gecikə bilər
Notifier siniflərinin birləşməsi`AutoDisposeNotifier`/`FamilyNotifier` adları ilə yazılmış siniflər yenilənməlidir
dart
// 1) valueOrNull → value
// v2:
final todos = ref.watch(todosProvider).valueOrNull;
// v3:
final todos = ref.watch(todosProvider).value;

// 2) Legacy provider-lər üçün import
// v3-də StateProvider/StateNotifierProvider/ChangeNotifierProvider:
import 'package:riverpod/legacy.dart';
// və ya yeni yanaşmaya keçid:
final counterProvider = NotifierProvider<Counter, int>(Counter.new);

// 3) Sealed AsyncValue → tam pattern matching
return switch (ref.watch(todosProvider)) {
  AsyncValue(:final value?) => TodoList(items: value),
  AsyncValue(:final error?) => ErrorView(message: '$error'),
  _ => const TodoSkeleton(),
};

// 4) Async-dan sonra provider-in hələ yaşadığını yoxlamaq
class Todos extends AsyncNotifier<List<Todo>> {
  @override
  Future<List<Todo>> build() => ref.watch(repositoryProvider).fetchAll();

  Future<void> refreshQuietly() async {
    final result = await ref.read(repositoryProvider).fetchAll();
    if (!ref.mounted) return; // v3: söküldükdən sonra müraciət xəta atır
    state = AsyncData(result);
  }
}

Migrasiyada ən çox rastlanan dörd düzəliş.

Migrasiyanın gözlənilməz hissəsi adətən avtomatik retry-dır: sənədə görə provider hesablanarkən exception baş verdikdə 10 dəfəyə qədər, 200 ms-dən 6.4 saniyəyə qədər eksponensial gecikmə ilə təkrar cəhd edilir. Bu, offline halında xəta ekranının gec görünməsinə səbəb ola bilər. retry parametri (provider, ProviderScope və ya ProviderContainer səviyyəsində) davranışı tənzimləməyə, retry: (retryCount, error) => null isə tamamilə söndürməyə imkan verir. Testlərdə vaxt gözləntisi olan hallar üçün bunu bilmək vacibdir.

📚 Mənbələr və sənədlər