Riverpod — Flutter के लिए संकलित निर्भरता प्रबंधन

लेखक: IT Sectr प्रकाशित: 2026-02-19 पढ़ने का समय: 7 मिनट

Riverpod — Flutter के लिए एक संकलित अवस्था और निर्भरता प्रबंधक, जिसे Remi Rousselet ने 2021 में Provider के उत्तराधिकारी के रूप में बनाया। Riverpod Provider की मूलभूत समस्याओं को हल करता है: संकलन-समय जाँच का अभाव, BuildContext पर निर्भरता, और ProviderNotFoundException के साथ जटिलता। pub.dev के अनुसार, पैकेज को 5 हज़ार से अधिक लाइक मिले हैं और यह नए प्रोजेक्ट्स में Provider को सक्रिय रूप से बदल रहा है।

मुख्य बिंदु

  • ProviderRef — प्रदाता के अंदर अन्य प्रदाताओं तक पहुँचने के लिए ऑब्जेक्ट
  • AsyncValue — loading/error/data अवस्थाओं के साथ अतुल्यकालिक डेटा के लिए आवरण
  • Notifier — परिवर्तन विधियों के साथ परिवर्तनीय अवस्था के लिए क्लास
  • ProviderScope — मूल विजेट जो सभी प्रदाताओं का प्रबंधन करता है
  • Code Generation — स्वचालित प्रदाता निर्माण के लिए @riverpod एनोटेशन

Riverpod क्या है?

Riverpod Flutter के लिए एक अवस्था प्रबंधन और निर्भरता इंजेक्शन लाइब्रेरी है जो प्रदाता विवरणों को सुरक्षित Dart कोड में संकलित करती है। Provider के विपरीत, Riverpod प्रदाता BuildContext से बंधे नहीं होते: वे वैश्विक रूप से या ProviderScope में बनाए जाते हैं और कहीं से भी पहुँच योग्य होते हैं। कंपाइलर बिल्ड समय पर प्रकार, निर्भरताएँ और प्रदाता ग्राफ की अखंडता की जाँच करता है, जिससे ProviderNotFoundException जैसी रनटाइम त्रुटियाँ समाप्त हो जाती हैं।

Riverpod परीक्षण के लिए override मॉडल का उपयोग करता है: प्रत्येक प्रदाता को ProviderScope.overrideWith के माध्यम से उपवर्ग बनाए या इंटरफ़ेस मॉक किए बिना ओवरराइड किया जा सकता है। यह परीक्षण को पृथक बनाता है: प्रत्येक परीक्षण को निर्भरता ग्राफ की अपनी प्रतिलिपि मिलती है जो पूरी तरह से नियंत्रित होती है।

Flutter Community Survey 2025 के अनुसार, Riverpod Provider और BLoC के बाद लोकप्रियता में तीसरे स्थान पर है। हालाँकि, Riverpod सबसे तेज़ी से बढ़ने वाला पैकेज है: 2024 में +120% इंस्टॉल। मुख्य कारण: संकलन-समय सुरक्षा, कोई ProviderNotFoundException नहीं, AsyncValue के माध्यम से अंतर्निहित अतुल्यकालिक समर्थन।

प्रदाताओं के प्रकार

Riverpod 8 प्रकार के प्रदाता प्रदान करता है, प्रत्येक एक विशिष्ट परिदृश्य के लिए: Provider (स्थिरांक/सेवा), StateProvider (आदिम अवस्था), StateNotifierProvider (StateNotifier के साथ जटिल तर्क), ChangeNotifierProvider (Provider से माइग्रेशन के लिए), FutureProvider (अतुल्यकालिक डेटा, एक बार), StreamProvider (प्रतिक्रियाशील स्ट्रीम), NotifierProvider (नया API, Flutter 3.10+) और AsyncNotifierProvider (अतुल्यकालिक 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 — अन्य प्रदाताओं तक पहुँचने के लिए प्रत्येक प्रदाता को पारित ऑब्जेक्ट। ref.watch — परिवर्तनों की सदस्यता, ref.read — एक बार पढ़ना, ref.invalidate — कैश रीसेट। ProviderRef Provider से BuildContext को बदलता है: कोई भी प्रदाता विजेट ट्री तक पहुँच के बिना अन्य प्रदाताओं को पढ़ सकता है। यह UI परत के बाहर निर्भरता ग्राफ बनाने की अनुमति देता है।

ProviderScope — मूल विजेट, Riverpod के काम करने के लिए अनिवार्य। ProviderScope सभी प्रदाताओं को संग्रहीत करता है, उनके जीवनचक्र का प्रबंधन करता है और मानों को कैश करता है। ProviderScope के बिना ऐप ProviderNotFoundException के साथ क्रैश हो जाएगा। ProviderScope नेस्टेड हो सकता है — नेस्टेड स्कोप मूल प्रदाताओं को ओवरराइड करता है, जिसका उपयोग परीक्षण और सुविधा पृथक्करण के लिए किया जाता है।

AsyncValue और अतुल्यकालिकता के साथ कार्य

AsyncValue — अतुल्यकालिक अवस्था का प्रतिनिधित्व करने के लिए Riverpod की सील्ड क्लास। AsyncValue के तीन रूप हैं: AsyncData (सफल डेटा), AsyncError (त्रुटि), AsyncLoading (लोड हो रहा है)। loading/error/data के बीच मैन्युअल रूप से स्विच करने के बजाय, प्रत्येक FutureProvider या StreamProvider स्वचालित रूप से AsyncValue लौटाता है, और विजेट ref.watch के माध्यम से तीनों अवस्थाओं को संभालता है।

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 — तीनों अवस्थाओं के पैटर्न-मिलान के लिए विधि। कंपाइलर जाँचता है कि तीनों मामले संभाले गए हैं — यदि आप loading या error भूल जाते हैं, तो कोड संकलित नहीं होगा। AsyncValue.whenData — केवल डेटा के लिए (यदि loading/error की आवश्यकता नहीं है)। AsyncValue.guard — अपवादों को AsyncError में बदलने के लिए try-catch पर आवरण। keepAlive — एक फ़्लैग जो प्रदाता कैश को दायरे से बाहर होने पर नष्ट होने से रोकता है।

कोड जनरेशन और @riverpod

कोड जनरेशन — Riverpod 2.0+ की एक प्रमुख विशेषता। फ़ंक्शन पर @riverpod एनोटेशन स्वचालित रूप से सही प्रकार, रिफैक्टरिंग समर्थन और ऑटोकंप्लीट के साथ एक प्रदाता उत्पन्न करता है। कोड जनरेशन riverpod_generator और build_runner का उपयोग करता है। डेवलपर एक शुद्ध फ़ंक्शन लिखता है, और बाकी सब कुछ — प्रकार, क्लास, फ़ैक्टरी कंस्ट्रक्टर — स्वचालित रूप से उत्पन्न होते हैं।

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

// उत्पन्न: final helloWorldProvider = Provider((ref) => 'Hello World');

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

Notifier — कोड जनरेशन के साथ परिवर्तनीय अवस्था के लिए नया API। Notifier एक build() विधि और अवस्था परिवर्तन विधियों वाली क्लास है। StateNotifier के विपरीत, Notifier को अलग अवस्था क्लास की आवश्यकता नहीं होती और यह getter/setter के माध्यम से state तक सीधी पहुँच प्रदान करता है। Riverpod @riverpod से एनोटेटेड प्रत्येक Notifier क्लास के लिए स्वचालित रूप से NotifierProvider उत्पन्न करता है।

build_runner: कोड जनरेशन dart run build_runner build कमांड से चलाया जाता है। उत्पन्न फ़ाइलों का .g.dart सफ़िक्स होता है और स्रोत कोड में आयात किया जाता है। जब एनोटेशन या प्रदाता प्रकार बदलते हैं, तो कोड जनरेशन को फिर से चलाने की आवश्यकता होती है। Riverpod 2.x सभी नए प्रोजेक्ट्स के लिए कोड जनरेशन की सिफारिश करता है — मैन्युअल प्रदाता निर्माण पुराना हो रहा है।

Riverpod बनाम Provider

मुख्य अंतर Riverpod और Provider के बीच: BuildContext से स्वतंत्रता, संकलन-समय सुरक्षा, अंतर्निहित अतुल्यकालिक समर्थन, स्वचालित कैशिंग, और override के माध्यम से परीक्षण। Provider को अवस्था तक पहुँचने के लिए BuildContext की आवश्यकता होती है (context.watch, context.read), Riverpod WidgetRef और वैश्विक रूप से घोषित प्रदाताओं का उपयोग करता है।

विशेषताProviderRiverpod
BuildContext निर्भरताहाँनहीं
संकलन-समय जाँचनहींहाँ (@riverpod के माध्यम से)
ProviderNotFoundExceptionरनटाइमअसंभव
अतुल्यकालिकतामैन्युअलAsyncValue (अंतर्निहित)
परीक्षणProvider में आवरणProviderScope.overrideWith
कैशिंगनहींस्वचालित + keepAlive

Provider से माइग्रेशन: Riverpod बिना पुनर्लेखन के मौजूदा ChangeNotifier का उपयोग करने के लिए ChangeNotifierProvider.adaptive का समर्थन करता है। क्रमिक माइग्रेशन: पहले नई सुविधाएँ Riverpod पर लिखी जाती हैं, फिर पुराने Provider इंस्टेंस को एडॉप्टर के माध्यम से Riverpod प्रदाताओं से बदल दिया जाता है। दोनों पैकेज एक प्रोजेक्ट में सह-अस्तित्व में रह सकते हैं, जिससे विकास को रोके बिना माइग्रेट करना संभव होता है।

Riverpod का परीक्षण

Riverpod का परीक्षण ProviderScope.overrideWith पर आधारित है। प्रत्येक प्रदाता बिना मॉक या DI कंटेनरों के परीक्षण ProviderScope के अंदर ओवरराइड किया जाता है। ProviderContainer — Flutter के बिना परीक्षणों के लिए पृथक वातावरण (शुद्ध Dart), जो विजेट रेंडरिंग के बिना प्रदाताओं का परीक्षण करने की अनुमति देता है।

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 के बिना। विजेट के बिना प्रदाताओं के यूनिट परीक्षण के लिए ProviderContainer का उपयोग करें। overrideWithValue — किसी विशिष्ट मान से प्रदाता को बदलना। overrideWith — प्रदाता फ़ैक्टरी से बदलना (सेवाओं को मॉक करने के लिए)। autodispose — परीक्षणों में जाँचें कि container.dispose() का उपयोग करके प्रदाता दायरे से बाहर होने पर नष्ट हो जाता है।

अक्सर पूछे जाने वाले प्रश्न

Riverpod BLoC से कैसे अलग है?

Riverpod वैश्विक प्रदाताओं, AsyncValue और कोड जनरेशन के साथ अवस्था प्रबंधन लाइब्रेरी है। BLoC Event → Stream → State के साथ एक आर्किटेक्चरल पैटर्न है। Riverpod सीखने में आसान है और @riverpod एनोटेशन के माध्यम से बेहतर DX प्रदान करता है। BLoC BlocObserver के माध्यम से सख्त व्यावसायिक तर्क पृथक्करण और Event ट्रेसिंग प्रदान करता है। चुनाव प्रोजेक्ट प्रतिमान पर निर्भर करता है: Riverpod Provider के करीब है, BLoC — प्रतिक्रियाशील स्ट्रीम के।

Riverpod में autodispose क्या है?

Autodispose एक तंत्र है जो प्रदाता को स्वचालित रूप से नष्ट कर देता है जब कोई उसकी सदस्यता नहीं लेता है। डिफ़ॉल्ट रूप से, सभी Riverpod प्रदाता autodispose करते हैं: जब विजेट ट्री से बाहर निकलता है, तो प्रदाता मेमोरी से हटा दिया जाता है। keepAlive — एक फ़्लैग जो उन प्रदाताओं के लिए autodispose को अक्षम करता है जिन्हें हमेशा जीवित रहना चाहिए (API क्लाइंट, रिपॉजिटरी, सेटिंग्स)। यह मेमोरी लीक को रोकता है — अप्रयुक्त प्रदाता स्वचालित रूप से नष्ट हो जाते हैं।

ref.invalidate कैसे काम करता है?

ref.invalidate — एक विधि जो प्रदाता कैश को जबरन रीसेट करती है। invalidate के बाद, अगली पढ़ाई पर प्रदाता फिर से बनाया जाता है: FutureProvider async फ़ंक्शन को फिर से निष्पादित करता है, StreamProvider स्ट्रीम को फिर से सब्सक्राइब करता है। डेटा रिफ्रेश को बाध्य करने के लिए invalidate का उपयोग करें (pull-to-refresh, उपयोगकर्ता स्विच)। ref.refresh — invalidate + पढ़ने का संयोजन: एक ऑपरेशन में रीसेट करता है और तुरंत नया मान पढ़ता है।

क्या Riverpod को कोड जनरेशन के बिना उपयोग किया जा सकता है?

हाँ। Riverpod 1.x केवल कोड जनरेशन के बिना काम करता है — प्रदाता मैन्युअल रूप से Provider(), StateNotifierProvider(), FutureProvider() आदि के माध्यम से बनाए जाते हैं। Riverpod 2.x दोनों दृष्टिकोणों का समर्थन करता है। कोड जनरेशन के बिना अधिक boilerplate है लेकिन build_runner और dart run build_runner build पर कोई निर्भरता नहीं है। छोटे प्रोजेक्ट्स (30 प्रदाताओं तक) के लिए मैन्युअल निर्माण उचित है, बड़े प्रोजेक्ट्स के लिए कोड जनरेशन अनिवार्य है।

Family प्रदाता क्या हैं?

Family — एक प्रदाता संशोधक जो बाहरी पैरामीटर स्वीकार करता है। उदाहरण के लिए, userProvider(123) — एक प्रदाता जो ID 123 वाले उपयोगकर्ता को लोड करता है। Family प्रदाता प्रत्येक अद्वितीय पैरामीटर के लिए परिणाम को अलग-अलग कैश करते हैं। उन वस्तुओं की सूचियों के लिए Family का उपयोग करें जहाँ प्रत्येक वस्तु ID द्वारा लोड की जाती है। Family संशोधक सभी प्रकार के प्रदाताओं के लिए उपलब्ध है: Provider.family, FutureProvider.family, StreamProvider.family।

सारांश

  • Riverpod — एक संकलित अवस्था प्रबंधक, Provider का उत्तराधिकारी बिना ProviderNotFoundException के
  • ProviderRef — अन्य प्रदाताओं के अंदर प्रदाताओं तक पहुँचने के लिए BuildContext का विकल्प
  • AsyncValue — अतुल्यकालिक डेटा के लिए loading/error/data अवस्थाओं वाली सील्ड क्लास
  • @riverpod कोड जनरेशन — स्वचालित प्रकार अनुमान और प्रदाता फ़ैक्टरी
  • ProviderScope.overrideWith — बिना मॉक और DI कंटेनरों के पृथक परीक्षण
  • Family — व्यक्तिगत कैशिंग के साथ पैरामीटरीकृत प्रदाता
  • autodispose और keepAlive — स्वचालित प्रदाता जीवनचक्र प्रबंधन

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें