Riverpod — Flutter için Derlenmiş Bağımlılık Yönetimi

Yazar: IT Sectr Yayınlanma: 2026-02-19 Okuma süresi: 7 dk

Riverpod — Flutter için derlenmiş bir durum ve bağımlılık yöneticisi, 2021 yılında Remi Rousselet tarafından Provider'ın halefi olarak oluşturuldu. Riverpod, Provider'ın temel sorunlarını çözer: derleme zamanı denetimi eksikliği, BuildContext bağımlılığı ve ProviderNotFoundException karmaşıklığı.pub.dev'a göre, paket 5 binden fazla beğeni aldı ve yeni projelerde Provider'ı aktif olarak değiştiriyor.

Ana Noktalar

  • ProviderRef — bir sağlayıcı içinde diğer sağlayıcılara erişmek için nesne
  • AsyncValue — loading/error/data durumlarıyla asenkron veriler için sarmalayıcı
  • Notifier — değişim yöntemleriyle değişebilir durum için sınıf
  • ProviderScope — tüm sağlayıcıları yöneten kök widget
  • Code Generation — otomatik sağlayıcı oluşturma için @riverpod notasyonları

Riverpod Nedir?

Riverpod, sağlayıcı tanımlarını güvenli Dart koduna derleyen, Flutter için bir durum yönetimi ve bağımlılık enjeksiyon kütüphanesidir. Provider'ın aksine, Riverpod sağlayıcıları BuildContext'e bağlı değildir: global olarak veya ProviderScope içinde oluşturulurlar ve her yerden erişilebilirler. Derleyici, derleme zamanında türleri, bağımlılıkları ve sağlayıcı grafiğinin bütünlüğünü denetleyerek ProviderNotFoundException gibi çalışma zamanı hatalarını ortadan kaldırır.

Riverpod, test için override modelini kullanır: her sağlayıcı, alt sınıflar oluşturmadan veya arayüzleri mocklamadan ProviderScope.overrideWith aracılığıyla geçersiz kılınabilir. Bu, testleri izole hale getirir: her test, tamamen kontrol edilen bağımlılık grafiğinin kendi kopyasını alır.

Flutter Community Survey 2025'e göre, Riverpod popülerlikte Provider ve BLoC'tan sonra üçüncü sırada yer alıyor. Ancak Riverpod en hızlı büyüyen pakettir: 2024'te +120% kurulum. Ana nedenler: derleme zamanı güvenliği, ProviderNotFoundException olmaması, AsyncValue aracılığıyla yerleşik asenkron destek.

Sağlayıcı Türleri

Riverpod 8 tür sağlayıcı sunar, her biri belirli bir senaryo için: Provider (sabit/hizmet), StateProvider (ilkel durum), StateNotifierProvider (StateNotifier ile karmaşık mantık), ChangeNotifierProvider (Provider'dan geçiş için), FutureProvider (asenkron veri, tek seferlik), StreamProvider (reaktif akış), NotifierProvider (yeni API, Flutter 3.10+) ve AsyncNotifierProvider (asenkron Notifier).

Dart
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 — diğer sağlayıcılara erişmek için her sağlayıcıya iletilen nesne. ref.watch — değişikliklere abonelik, ref.read — tek seferlik okuma, ref.invalidate — önbellek sıfırlama. ProviderRef, Provider'ın BuildContext'ini değiştirir: herhangi bir sağlayıcı, widget ağacına erişmeden diğer sağlayıcıları okuyabilir. Bu, UI katmanının dışında bir bağımlılık grafiği oluşturmayı sağlar.

ProviderScope — Riverpod'un çalışması için zorunlu olan kök widget. ProviderScope tüm sağlayıcıları depolar, yaşam döngülerini yönetir ve değerleri önbelleğe alır. ProviderScope olmadan uygulama ProviderNotFoundException ile çöker. ProviderScope iç içe geçebilir — iç içe bir kapsam üst sağlayıcıları geçersiz kılar ve test ve özellik izolasyonu için kullanılır.

AsyncValue ve Asenkron ile Çalışma

AsyncValue — asenkron durumu temsil etmek için Riverpod'un sealed sınıfı. AsyncValue'un üç çeşidi vardır: AsyncData (başarılı veri), AsyncError (hata), AsyncLoading (yükleniyor). loading/error/data arasında manuel olarak geçiş yapmak yerine, her FutureProvider veya StreamProvider otomatik olarak AsyncValue döndürür ve widget ref.watch aracılığıyla üç durumu da işler.

Dart
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 — üç durumun tümünü desen eşleme için bir yöntem. Derleyici, üç durumun da ele alındığını denetler — loading veya error'u unutursanız, kod derlenmez. AsyncValue.whenData — yalnızca veri için (loading/error gerekli değilse). AsyncValue.guard — istisnaları AsyncError'a dönüştürmek için try-catch sarmalayıcısı. keepAlive — sağlayıcı önbelleğinin kapsam dışına çıktığında yok edilmesini önleyen bir bayrak.

Kod Oluşturma ve @riverpod

Kod oluşturma — Riverpod 2.0+'ın temel bir özelliği. Bir işlevdeki @riverpod notasyonu, doğru tür, yeniden düzenleme desteği ve otomatik tamamlama ile otomatik olarak bir sağlayıcı oluşturur. Kod oluşturma riverpod_generator ve build_runner kullanır. Geliştirici saf bir işlev yazar ve geri kalan her şey — türler, sınıflar, fabrika yapıcıları — otomatik olarak oluşturulur.

Dart
@riverpod
String helloWorld(HelloWorldRef ref) {
  return 'Hello World';
}

// Oluşturuldu: final helloWorldProvider = Provider((ref) => 'Hello World');

@riverpod
class Counter extends _$Counter {
  int build() => 0;
  void increment() => state++;
}

Notifier — kod oluşturma ile değişebilir durum için yeni API. Notifier, bir build() yöntemi ve durum değiştirme yöntemleri olan bir sınıftır. StateNotifier'ın aksine, Notifier ayrı bir durum sınıfı gerektirmez ve getter/setter aracılığıyla state'e doğrudan erişim sağlar. Riverpod, @riverpod ile notasyon eklenmiş her Notifier sınıfı için otomatik olarak NotifierProvider oluşturur.

build_runner: kod oluşturma dart run build_runner build komutuyla çalıştırılır. Oluşturulan dosyalar .g.dart sonekine sahiptir ve kaynak koduna aktarılır. Notasyonlar veya sağlayıcı türleri değiştiğinde, kod oluşturmanın yeniden çalıştırılması gerekir. Riverpod 2.x, tüm yeni projeler için kod oluşturmayı önerir — manuel sağlayıcı oluşturma eskimektedir.

Riverpod vs Provider

Temel farklar Riverpod ve Provider arasında: BuildContext'ten bağımsızlık, derleme zamanı güvenliği, yerleşik asenkron destek, otomatik önbellekleme ve override aracılığıyla test. Provider, duruma erişmek için BuildContext gerektirir (context.watch, context.read), Riverpod WidgetRef ve global olarak bildirilen sağlayıcıları kullanır.

ÖzellikProviderRiverpod
BuildContext bağımlılığıEvetHayır
Derleme zamanı denetimiHayırEvet (@riverpod ile)
ProviderNotFoundExceptionÇalışma zamanıİmkansız
AsenkronManuelAsyncValue (yerleşik)
TestProvider'da sarmalayıcıProviderScope.overrideWith
ÖnbelleklemeHayırOtomatik + keepAlive

Provider'dan geçiş: Riverpod, yeniden yazmadan mevcut ChangeNotifier'ı kullanmak için ChangeNotifierProvider.adaptive'yi destekler. Kademeli geçiş: önce yeni özellikler Riverpod ile yazılır, ardından eski Provider örnekleri bir adaptör aracılığıyla Riverpod sağlayıcılarıyla değiştirilir. Her iki paket bir projede birlikte var olabilir ve geliştirmeyi dondurmadan geçişe izin verir.

Riverpod Test Etme

Riverpod test etme ProviderScope.overrideWith üzerine kuruludur. Her sağlayıcı, mock veya DI kapsayıcıları olmadan bir test ProviderScope içinde geçersiz kılınır. ProviderContainer — Flutter olmadan testler için izole bir ortam (saf Dart), widget oluşturmadan sağlayıcıları test etmeye izin verir.

Dart
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'sız. Widget'sız sağlayıcıların birim testleri için ProviderContainer kullanın. overrideWithValue — bir sağlayıcıyı belirli bir değerle değiştirme. overrideWith — bir sağlayıcı fabrikasıyla değiştirme (hizmetleri mocklamak için). autodispose — testlerde, container.dispose() kullanarak sağlayıcının kapsam dışına çıktığında yok edildiğini doğrulayın.

Sıkça Sorulan Sorular

Riverpod, BLoC'tan nasıl farklıdır?

Riverpod, global sağlayıcılar, AsyncValue ve kod oluşturma ile bir durum yönetimi kütüphanesidir. BLoC, Event → Stream → State ile bir mimari desendir. Riverpod öğrenmesi daha kolaydır ve @riverpod notasyonları aracılığıyla daha iyi DX sağlar. BLoC, BlocObserver aracılığıyla sıkı iş mantığı izolasyonu ve Olay izleme sağlar. Seçim proje paradigmasına bağlıdır: Riverpod Provider'a daha yakındır, BLoC — reaktif akışlara.

Riverpod'da autodispose nedir?

Autodispose, kimse abone olmadığında bir sağlayıcıyı otomatik olarak yok etme mekanizmasıdır. Varsayılan olarak, tüm Riverpod sağlayıcıları autodispose yapar: bir widget ağaçtan çıktığında, sağlayıcı bellekten kaldırılır. keepAlive — her zaman yaşaması gereken sağlayıcılar (API istemcileri, depolar, ayarlar) için autodispose'u devre dışı bırakan bir bayrak. Bu, bellek sızıntılarını önler — kullanılmayan sağlayıcılar otomatik olarak yok edilir.

ref.invalidate nasıl çalışır?

ref.invalidate — sağlayıcı önbelleğini zorla sıfırlayan bir yöntem. invalidate'den sonra, sonraki okumada sağlayıcı yeniden oluşturulur: FutureProvider asenkron işlevi yeniden yürütür, StreamProvider akışa yeniden abone olur. Veri yenilemeyi zorlamak için invalidate kullanın (çek-yenile, kullanıcı değişikliği). ref.refresh — invalidate + okuma kombinasyonu: tek bir işlemde sıfırlar ve hemen yeni değeri okur.

Riverpod kod oluşturma olmadan kullanılabilir mi?

Evet. Riverpod 1.x yalnızca kod oluşturma olmadan çalışır — sağlayıcılar Provider(), StateNotifierProvider(), FutureProvider() vb. kullanılarak manuel olarak oluşturulur. Riverpod 2.x her iki yaklaşımı da destekler. Kod oluşturma olmadan daha fazla tekrar eden kod vardır ancak build_runner ve dart run build_runner build'e bağımlılık yoktur. Küçük projeler (30 sağlayıcıya kadar) için manuel oluşturma haklıdır; büyük projeler için kod oluşturma zorunludur.

Family sağlayıcılar nedir?

Family — harici bir parametre kabul eden bir sağlayıcı değiştiricisi. Örneğin, userProvider(123) — ID 123 olan bir kullanıcıyı yükleyen sağlayıcı. Family sağlayıcıları, her benzersiz parametre için sonucu ayrı ayrı önbelleğe alır. Her öğenin kimlikle yüklendiği öğe listeleri için Family kullanın. Family değiştiricisi tüm sağlayıcı türleri için kullanılabilir: Provider.family, FutureProvider.family, StreamProvider.family.

Özet

  • Riverpod — ProviderNotFoundException olmayan, derlenmiş durum yöneticisi, Provider'ın halefi
  • ProviderRef — diğer sağlayıcılar içinde sağlayıcılara erişmek için BuildContext alternatifi
  • AsyncValue — asenkron veriler için loading/error/data durumlarına sahip sealed sınıf
  • @riverpod kod oluşturma — otomatik tür çıkarımı ve sağlayıcı fabrikaları
  • ProviderScope.overrideWith — mock ve DI kapsayıcıları olmadan izole test
  • Family — bireysel önbellekleme ile parametrelendirilmiş sağlayıcılar
  • autodispose ve keepAlive — otomatik sağlayıcı yaşam döngüsü yönetimi

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun