Riverpod — Flutter üçün kompilə edilən vəziyyət və asılılıq meneceri, 2021-ci ildə Rémi Roussel tərəfindən Provider-in varisi olaraq yaradılmışdır. Riverpod Provider-in fundamental problemlərini həll edir: kompilə yoxlamasının olmaması, BuildContext-dən asılılıq və ProviderNotFoundException ilə çətinlik. pub.dev məlumatlarına görə, paket 5 mindən çox bəyənmə toplamış və yeni layihələrdə Provider-i aktiv şəkildə əvəz edir.
Əsas
Riverpod — Flutter-də vəziyyətin idarə edilməsi və asılılıqların daxil edilməsi üçün kitabxana, provider təsvirlərini təhlükəsiz Dart koduna kompilə edir. Provider-dən fərqli olaraq, Riverpod provider-ləri BuildContext-ə bağlı deyil: onlar qlobal olaraq və ya ProviderScope-də yaradılır və istənilən yerdən əlçatandır. Kompilator qurma mərhələsində provider qrafının növlərini, asılılıqlarını və bütövlüyünü yoxlayır və ProviderNotFoundException kimi runtime səhvlərini aradan qaldırır.
Riverpod test üçün override modelindən istifadə edir: hər bir provider alt siniflər yaratmadan və ya interfeysləri mock etmədən ProviderScope.overrideWith vasitəsilə ləğv edilə bilər. Bu, testi izolyasiya edir: hər test tam idarə olunan asılılıq qrafının öz nüsxəsini alır.
Flutter Community Survey 2025 məlumatlarına görə, Riverpod populyarlıq baxımından Provider və BLoC-dan sonra üçüncü yerdədir. Eyni zamanda Riverpod ən sürətli böyüyən paketdir: 2024-cü ildə +120% quraşdırma. Əsas səbəblər: kompilə təhlükəsizliyi, ProviderNotFoundException-nin olmaması, AsyncValue vasitəsilə asinxronluğun daxili dəstəyi.
Riverpod hər biri konkret ssenari üçün 8 növ provider təqdim edir: Provider (sabit/xidmət), StateProvider (sadə vəziyyət), StateNotifierProvider (StateNotifier ilə mürəkkəb məntiq), ChangeNotifierProvider (Provider-dən miqrasiya üçün), FutureProvider (asinxron məlumatlar, bir dəfə), StreamProvider (reaktiv axın), NotifierProvider (yeni API, Flutter 3.10+) və AsyncNotifierProvider (asinxron Notifier).
final counterProvider = StateNotifierProvider<CounterNotifier, int>((ref) {
return CounterNotifier();
});
class CounterNotifier extends StateNotifier<int> {
CounterNotifier() : super(0);
void increment() => state++;
void decrement() => state--;
}
class CounterScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Text('$count');
}
}ProviderRef — hər bir providerə digər providerlərə daxil olmaq üçün ötürülən obyekt. ref.watch — dəyişikliklərə abunə olmaq, ref.read — birdəfəlik oxumaq, ref.invalidate — keşi sıfırlamaq. ProviderRef Provider-dən BuildContext-i əvəz edir: istənilən provider vidjet ağacına daxil olmadan digər providerləri oxuya bilər. Bu, UI qatından kənarda asılılıq qrafı qurmağa imkan verir.
ProviderScope — Riverpod-un işləməsi üçün məcburi olan kök vidjet. ProviderScope bütün providerləri saxlayır, onların həyat dövrünü idarə edir və dəyərləri keşləyir. ProviderScope olmadan proqram ProviderNotFoundException ilə çökəcək. ProviderScope iç-içə ola bilər — iç-içə scopes valideyn providerlərini ləğv edir, bu da test və funksiyaların izolyasiyası üçün istifadə olunur.
AsyncValue — asinxron vəziyyəti təmsil etmək üçün Riverpod-un sealed sinfi. AsyncValue-un üç variantı var: AsyncData (uğurlu məlumat), AsyncError (xəta), AsyncLoading (yüklənir). loading/error/data arasında əl ilə keçid etmək əvəzinə, hər FutureProvider və ya StreamProvider avtomatik olaraq AsyncValue qaytarır və vidjet ref.watch vasitəsilə hər üç vəziyyəti idarə edir.
final userProvider = FutureProvider((ref) async {
final api = ref.watch(apiProvider);
return await api.fetchUser();
});
class UserScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final userAsync = ref.watch(userProvider);
return userAsync.when(
data: (user) => UserWidget(user),
error: (e, _) => ErrorWidget(e.toString()),
loading: () => CircularProgressIndicator(),
);
}
}AsyncValue.when — hər üç vəziyyətin nümunə uyğunlaşdırılması üçün metod. Kompilator bütün üç halın idarə olunduğunu yoxlayır — loading və ya error unudularsa, kod kompilə olunmayacaq. AsyncValue.whenData — yalnız data üçün (loading/error lazım deyilsə). AsyncValue.guard — istisnanı AsyncError-ə çevirmək üçün try-catch sarğısı. keepAlive — görünmə diapazonundan çıxarkən provider keşinin məhv edilməsinin qarşısını alan bayraq.
Kodgenerasiya — Riverpod 2.0+-ın əsas xüsusiyyətidir. Funksiya üzərində @riverpod anotasiyası avtomatik olaraq düzgün tipə malik, refaktorinq dəstəyi və avtomatik tamamlama ilə provider yaradır. Kodgenerasiya riverpod_generator və build_runner istifadə edir. Tərtibatçı təmiz funksiya yazır, qalan hər şey — növlər, siniflər, fabrik konstruktorları — avtomatik generasiya olunur.
@riverpod
String helloWorld(HelloWorldRef ref) {
return 'Hello World';
}
// Yaradıldı: final helloWorldProvider = Provider((ref) => 'Hello World');
@riverpod
class Counter extends _$Counter {
int build() => 0;
void increment() => state++;
}Notifier — kodgenerasiya ilə mutasiya olunan vəziyyət üçün yeni API. Notifier build() metodu və vəziyyəti dəyişən metodları olan sinifdir. StateNotifier-dən fərqli olaraq, Notifier ayrıca vəziyyət sinfi tələb etmir və getter/setter vasitəsilə state-ə birbaşa giriş verir. Riverpod @riverpod anotasiyası olan hər Notifier sinfi üçün avtomatik NotifierProvider yaradır.
build_runner: kodgenerasiya dart run build_runner build əmri ilə işə salınır. Generasiya olunmuş fayllar .g.dart suffiksinə malikdir və mənbə koduna idxal olunur. Anotasiyalar və ya provider növləri dəyişdikdə kodgenerasiyanı yenidən işə salmaq lazımdır. Riverpod 2.x bütün yeni layihələr üçün kodgenerasiyanı tövsiyə edir — providerlərın əl ilə yaradılması köhnəlir.
Əsas fərqlər Riverpod ilə Provider arasında: BuildContext-dən müstəqillik, kompilə təhlükəsizliyi, asinxronlukla daxili iş, avtomatik keşləmə və override vasitəsilə test. Provider vəziyyətə daxil olmaq üçün BuildContext tələb edir (context.watch, context.read), Riverpod WidgetRef və qlobal elan edilmiş providerlərdən istifadə edir.
| Xüsusiyyət | Provider | Riverpod |
|---|---|---|
| BuildContext-dən asılılıq | Bəli | Xeyr |
| Kompilə yoxlaması | Xeyr | Bəli (@riverpod vasitəsilə) |
| ProviderNotFoundException | Runtime | Mümkün deyil |
| Asinxronluq | Əl ilə | AsyncValue (daxili) |
| Test | Provider-də sarğı | ProviderScope.overrideWith |
| Keşləmə | Xeyr | Avtomatik + keepAlive |
Provider-dən miqrasiya: Riverpod mövcud ChangeNotifier-ləri yenidən yazmadan istifadə etmək üçün ChangeNotifierProvider.adaptive-ni dəstəkləyir. Mərhələli miqrasiya: əvvəlcə yeni funksiyalar Riverpod-da yazılır, sonra köhnə Provider-lər adapter vasitəsilə Riverpod providerləri ilə əvəz olunur. Hər iki paket eyni layihədə birgə mövcud ola bilər ki, bu da inkişafı dondurmadan miqrasiyaya imkan verir.
Riverpod-un test edilməsi ProviderScope.overrideWith üzərində qurulub. Hər bir provider mock və DI konteynerləri olmadan test ProviderScope daxilində ləğv edilir. ProviderContainer — Flutter-siz (təmiz Dart) testlər üçün izolyasiya edilmiş mühit, providerləri vidjetləri göstərmədən test etməyə imkan verir.
import 'package:flutter_test/flutter_test.dart';
import 'package:riverpod/riverpod.dart';
void main() {
test('Counter increments correctly', () {
final container = ProviderContainer();
container.read(counterProvider.notifier).increment();
expect(container.read(counterProvider), 1);
});
testWidgets('UI updates on increment', (tester) async {
await tester.pumpWidget(
ProviderScope(
overrides: [counterProvider.overrideWithValue(5)],
child: CounterScreen(),
),
);
expect(find.text('5'), findsOneWidget);
});
}ProviderContainer — Flutter-siz. ProviderContainer-dan vidjetlər olmadan providerlərin vahid testləri üçün istifadə edin. overrideWithValue — providerı konkret dəyərlə əvəz etmək. overrideWith — provider fabriki ilə əvəz etmək (xidmətləri mock etmək üçün). autodispose — testlərdə providerın görünmə diapazonundan çıxdıqda container.dispose() ilə məhv olub-olmadığını yoxlayın.
Tez-tez verilən suallar
Riverpod — qlobal providerlər, AsyncValue və kodgenerasiya ilə vəziyyətin idarə edilməsi kitabxanası. BLoC — Event → Stream → State ilə arxitektura nümunəsi. Riverpod öyrənmək daha asandır və @riverpod anotasiyaları vasitəsilə daha yaxşı DX təmin edir. BLoC biznes məntiqinin ciddi izolyasiyasını və BlocObserver vasitəsilə Event izləməni verir. Seçim layihənin paradigmasından asılıdır: Riverpod Provider-ə, BLoC isə reaktiv axınlara daha yaxındır.
Autodispose — heç kim abunə olmadıqda providerın avtomatik məhv edilməsi mexanizmi. Varsayılan olaraq bütün Riverpod providerləri autodispose-dir: vidjet ağacdan çıxdıqda provider yaddaşdan silinir. keepAlive — həmişə yaşamalı olan providerlar (API müştəriləri, repozitorilər, parametrlər) üçün autodispose-u söndürən bayraq. Bu, yaddaş sızmalarının qarşısını alır — istifadə olunmayan providerlar avtomatik məhv edilir.
ref.invalidate — providerın keşini məcburi sıfırlayan metod. invalidate-dən sonra növbəti oxunuşda provider yenidən yaradılır: FutureProvider async funksiyasını təkrar icra edir, StreamProvider axına yenidən abunə olur. Məlumatları məcburi yeniləmək üçün invalidate istifadə edin (pull-to-refresh, istifadəçi dəyişikliyi). ref.refresh — invalidate + oxuma kombinasiyası: bir əməliyyatda keşi sıfırlayır və dərhal yeni dəyəri oxuyur.
Bəli. Riverpod 1.x yalnız kodgenerasiya olmadan işləyir — providerlar əl ilə Provider(), StateNotifierProvider(), FutureProvider() və s. vasitəsilə yaradılır. Riverpod 2.x hər iki yanaşmanı dəstəkləyir. Kodgenerasiya olmadan daha çox boilerplate var, lakin build_runner və dart run build_runner build-dən asılılıq yoxdur. Kiçik layihələr (30 providera qədər) üçün əl ilə yaratmaq əsaslandırılmışdır, böyük layihələr üçün kodgenerasiya məcburidir.
Family — xarici parametr qəbul edən provider modifikatoru. Məsələn, userProvider(123) — ID-si 123 olan istifadəçini yükləyən provider. Family-providerlar hər unikal parametr üçün nəticəni ayrıca keşləyir. Family-dən hər bir elementin ID ilə yükləndiyi elementlər siyahısı üçün istifadə edin. Family modifikatoru bütün provider növləri üçün mövcuddur: Provider.family, FutureProvider.family, StreamProvider.family.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun