Provider: nedir, Flutter uygulama durum yöneticisi

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

Provider — 2019 yılında Remi Rousselet tarafından InheritedWidget üzerine bir sarmalayıcı olarak oluşturulan Flutter için bir durum yönetimi paketidir. Provider, props drilling olmadan widget ağacında aşağıya veri gönderme sorununu çözer: herhangi bir widget, context.read<T>() veya context.watch<T>() aracılığıyla duruma erişebilir. pub.dev'e göre Provider, 25 binden fazla beğeniyle Flutter'ın en popüler durum yöneticisidir.

Önemli Noktalar

  • ChangeNotifier — abonelere değişiklikleri bildirmek için notifyListeners ile bir sınıf
  • Consumer — ChangeNotifier değiştiğinde yeniden oluşturan bir widget
  • MultiProvider — iç içe geçmeden birden çok Provider bileşimi
  • ProxyProvider — başka bir Provider'a bağımlı olan Provider
  • context.read / context.watch — abonelik olmadan ve abonelikle durumu okuma yöntemleri

Provider nedir?

Provider — InheritedWidget üzerine inşa edilmiş, Flutter'da durum yönetimi ve bağımlılık enjeksiyonu için bir pakettir. Provider, widget ağacında bir nesne (durum, hizmet, depo) sağlar ve veri değiştiğinde UI'yı otomatik olarak yeniden oluşturur. InheritedWidget'ın doğrudan kullanımının aksine, Provider tüm kalıp kodu ortadan kaldırır: InheritedWidget alt sınıfı yazmaya, statik of() yöntemi ayarlamaya veya iç içe geçmeyi yönetmeye gerek yoktur.

Provider, Google tarafından Flutter'da durum yönetimi için resmi olarak önerilen yöntemdir (Flutter Team, 2019-2023). Paket, Flutter Ekosisteminin bir parçasıdır ve Flutter ekibi tarafından bakımı yapılmaktadır. Çıkışında Provider, global değişkenler ve InheritedWidget'ın yerine önerilmiştir: herhangi bir nesneye yapıcıdan geçirilmeden her yerden erişilebilir.

Flutter Topluluk Anketi 2025'e göre Provider, Flutter uygulamalarının %72'sinde kullanılmaktadır. Popülerliğinin ana nedenleri: minimum giriş eşiği, yerleşik ChangeNotifier desteği, diğer mimarilerle (MVVM, BLoC) uyumluluk ve harici bağımlılıkların olmamasıdır.

ChangeNotifier ve notifyListeners

ChangeNotifier — Listener desenini uygulayan yerleşik bir Flutter sınıfıdır. ChangeNotifier, notifyListeners() çağrısı yaparak abonelere değişiklikleri bildirir. Provider bağlamında ChangeNotifier, durum için ana sınıftır: ChangeNotifier'ı genişleten bir sınıf, veri değişikliğinden sonra notifyListeners() çağıran alanlar ve yöntemlerle oluşturulur.

Dart
class CounterProvider extends ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }

  void reset() {
    _count = 0;
    notifyListeners();
  }
}

notifyListeners kuralları: veriyi tamamen değiştirdikten sonra çağırın — yöntemin ortasında değil, sonunda. Bir yöntem birden çok değişiklik yapıyorsa, her değişiklikten sonra değil, tüm değişikliklerden sonra bir kez notifyListeners() çağırın. Bu, tek bir mantıksal adımda birden çok yeniden çizimi önler. Toplu güncellemeler için, setState benzeri desenlerle birlikte notifyListeners kullanın.

ChangeNotifier alternatifleri: ValueNotifier — tek bir değer için (ilkel türler için iyi), StateNotifierstate_notifier paketinden (nadiren tek başına kullanılır). Çoğu Provider çözümü, yerleşik desteği ve basitliği nedeniyle ChangeNotifier kullanır.

Consumer ve context.watch

Consumer — ChangeNotifier'a abone olan ve her notifyListeners() çağrısında yeniden oluşturan bir widget'tır. Consumer, üç parametreli bir builder işlevi alır: context, model, child. Child — modele bağlı olmayan ve Consumer tarafından yeniden oluşturulmayan bir widget'tır. Bu bir optimizasyondur: Consumer statik bir widget (simge, verisiz metin) içeriyorsa, child aracılığıyla iletilir ve yeniden oluşturulmaz.

Dart
Consumer<CounterProvider>(
  builder: (context, provider, child) => Column(
    children: [
      child!, // yeniden oluşturulmaz
      Text('${provider.count}'),
      ElevatedButton(
        onPressed: () => provider.increment(),
        child: Icon(Icons.add),
      ),
    ],
  ),
  child: Text('Sayaç:'),
)

context.watch — bir Provider'a abone olmak için BuildContext uzantı yöntemidir. Modeli döndürür ve mevcut widget'ı değişikliklerine abone yapar. context.read — abonelik olmadan erişim (onPressed işleyicileri, initState ve dispose için). context.select — diğer alanlar değiştiğinde yeniden oluşturmadan modelin belirli bir alanına abonelik. Select, 10+ alanı olan karmaşık modeller için en verimli seçenektir.

Consumer, watch veya select ne zaman kullanılır: Consumer — optimizasyon için bir child widget gerektiğinde. watch — basit okuma için build yönteminde. select — modelin birden çok alanı olduğunda ancak widget yalnızca birine bağlı olduğunda. Provider, widget yok edildiğinde otomatik olarak aboneliği iptal eder ve bellek sızıntılarını önler.

MultiProvider ve ProxyProvider

MultiProvider — iç içe geçmeden birden çok Provider kaydetmek için bir widget'tır. 5 seviyeli Provider → Provider → Provider ağacı yerine MultiProvider, bir sağlayıcı listesi alır. Sonraki her Provider, öncekileri yapıcı aracılığıyla kullanabilir. MultiProvider, bir uygulamanın kök seviyesini düzenlemenin standart yoludur.

Dart
MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (_) => CartProvider()),
    ChangeNotifierProvider(create: (_) => AuthProvider()),
    ProxyProvider<AuthProvider, OrderProvider>(
      update: (_, auth, __) => OrderProvider(auth.userId),
    ),
  ],
  child: MaterialApp(home: HomePage()),
)

ProxyProvider — başka bir Provider'a bağımlı olan Provider'dır. ProxyProvider, diğer Provider'lardan değerler alır ve bunları kendi nesnesine iletir. Örneğin, OrderProvider AuthProvider'a bağlıdır (userId gerekir). AuthProvider değiştiğinde, ProxyProvider yeni userId ile OrderProvider'ı otomatik olarak yeniden oluşturur. ChangeNotifierProxyProvider — ChangeNotifier için ProxyProvider sürümüdür.

StreamProvider ve FutureProvider: StreamProvider bir Stream'e (Firebase, WebSocket) abone olur ve her yeni olayda Consumer'ı günceller. FutureProvider — asenkron başlatma için: bir Future çalıştırır, yükleme gösterir, ardından sonucu widget'lara iletir. Her ikisi de manuel abonelik yönetimi olmadan yaygın görevleri çözer.

Provider'ı test etme

Provider test edilirken widget, test değerleriyle bir MultiProvider içine sarılır. Test için gerçek bir API veya veritabanı gerekmez — Provider, taklit edilmiş bir nesneyle değiştirilir. provider paketi, test izolasyonu için ProviderScope sağlar — her test bağımsız olarak kendi Provider ağacını oluşturur.

Dart
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('Counter increments on button tap',
    (tester) async {
      await tester.pumpWidget(
        ChangeNotifierProvider(
          create: (_) => CounterProvider(),
          child: CounterScreen(),
        ),
      );
      await tester.tap(find.byKey(Key('increment')));
      await tester.pump();
      expect(find.text('1'), findsOneWidget);
    },
  );
}

MockProvider: Bir API'ye bağlı Provider ile widget'ları test etmek için, bir saplama alt sınıfı oluşturun veya mockito / mocktail kullanın. Provider özel taklit araçları gerektirmez — ChangeNotifier'ı genişleten herhangi bir nesne, gerçek hizmeti çağırmadan create aracılığıyla iletilebilir. Kolay değişim için Provider'ları arayüzler (soyut sınıf) aracılığıyla programlayın.

Provider: performans ve sınırlamalar

Provider performansı InheritedWidget'a dayanır: bir Provider değiştiğinde, context.watch veya Consumer aracılığıyla abone olunan tüm widget'lar yeniden oluşturulur. Gereksiz yeniden çizimleri önlemek için, context.select (belirli bir alana abonelik), Consumer child parametresiyle ve statik widget'lar için const kullanın. Provider, değişikliklere abone olmayan dalları yeniden oluşturmaz.

YöntemAbonelikYeniden OluşturmaKullanım
context.watchTüm modelHerhangi bir değişiklikBasit widget'lar
ConsumerTüm modelHerhangi bir değişiklikChild optimizasyonu ile
context.selectBelirli alanSadece alan değişinceKarmaşık modeller
context.readHayırAslaOlay işleyicileri

Sınırlamalar: Provider, olay düzeyinde iş mantığı izolasyonunu (BLoC gibi) desteklemez. Tüm değişiklikler, ChangeNotifier yöntemlerine doğrudan çağrılarla gerçekleşir ve bu da kontrol edilemeyen değişiklik zincirlerine yol açabilir. Karmaşık senaryolar için (birden çok asenkron işlem, karmaşık doğrulama), Provider BLoC ve Riverpod'un gerisinde kalır.

Provider'dan geçiş: Provider diğer paketlerle kolayca birleştirilebilir. Riverpod'a geçmek için ChangeNotifierProvider.adaptive kullanın — mevcut ChangeNotifier'ları yeniden yazmadan Riverpod ile kullanmaya izin veren bir bağdaştırıcı. BLoC için — BlocProvider, ChangeNotifier'ı kademeli olarak Bloc ile değiştirerek bir Provider ağacının içine yerleştirilebilir.

Sıkça Sorulan Sorular

Provider, BLoC'dan nasıl farklıdır?

Provider — ChangeNotifier ile bağımlılık enjeksiyonu için InheritedWidget üzerinde bir sarmalayıcı. BLoC — mantık izolasyonu için Event + Stream ile bir mimari desen. Provider öğrenmesi daha kolay, BLoC kodu daha katı şekilde yapılandırır. Provider küçük uygulamalar ve UI durumu için uygundur, BLoC karmaşık iş mantığı için. Flutter Community 2025'e göre, her ikisi de sıklıkla aynı projede birlikte kullanılır.

ChangeNotifierProvider nedir?

ChangeNotifierProvider — ChangeNotifier örnekleri için bir Provider türüdür. Nesneyi create aracılığıyla oluşturur, alt öğelerine sağlar ve notifyListeners çağrıldığında Consumer'ı yeniden oluşturur. ChangeNotifierProvider, ağaçtan kaldırıldığında ChangeNotifier üzerinde otomatik olarak dispose çağrısı yapar. Üç oluşturma yöntemi vardır: ChangeNotifierProvider.value (mevcut nesne için), ChangeNotifierProvider (tembel oluşturma için) ve ChangeNotifierProvider.create (açık tembel oluşturma için).

Provider ile gereksiz yeniden oluşturmalar nasıl önlenir?

context.watch yerine context.select kullanın — widget yalnızca seçilen alan değiştiğinde yeniden oluşur. Büyük ChangeNotifier'ı birkaç küçüğe bölün (bir model — bir sorumluluk). Statik parçalar için Consumer child kullanın. Listeler için, anahtarlarla ListView.builder kullanın. Provider DevTools (Flutter Inspector), hangi widget'ların yeniden oluşturulduğunu ve nedenini gösterir.

Provider, ChangeNotifier olmadan kullanılabilir mi?

Evet. Provider (ChangeNotifier olmadan) — değişmez nesneleri (depo, API istemcisi, yapılandırma) enjekte etmek için. ValueListenableProvider — ValueNotifier için. StreamProvider — Stream (Firebase, WebSocket) için. FutureProvider — Future (başlangıçta yapılandırma yükleme) için. ProxyProvider — diğer Provider'lara bağlı olan Provider'lar için. ChangeNotifier yalnızca UI güncellemesi olan değiştirilebilir durum için gereklidir.

ProviderNotFoundException nedir?

ProviderNotFoundException — widget ağacında daha yukarıda bildirilmemiş bir Provider alınmaya çalışıldığında oluşan bir çalışma zamanı istisnasıdır. Yaygın nedenler: Provider, onu okumaya çalışan widget'tan daha aşağıda bildirilmiştir; Provider bir rotada bildirilmiş ve başka bir rotada okunuyor; türde yazım hatası. Çözüm: Provider'ı ağaçta yukarı taşıyın veya genel bağımlılıklar için MaterialApp düzeyinde MultiProvider kullanın.

Özet

  • Provider — Flutter'da durum yönetimi ve DI için InheritedWidget üzerinde bir sarmalayıcı
  • ChangeNotifier — tepkisel UI güncellemeleri için notifyListeners ile bir sınıf
  • Consumer ve context.watch — otomatik yeniden oluşturma ile değişiklik aboneliği
  • MultiProvider — ağaç iç içeliği olmadan sağlayıcıların bileşimi
  • ProxyProvider — Provider'lar arasında bağımlılık zinciri
  • context.select — modelin belirli bir alanına hedefli abonelik
  • StreamProvider ve FutureProvider — tepkisel ve asenkron veriler için yerleşik destek

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