dartpub.dev DartNative · beta
plugins / provider_scope
pr

provider_scope

v0.3.0 MIT

Use Riverpod naturally in DartNative widget trees.

provider_scope is a bridge package that enables DartNative applications to integrate Riverpod state management into DartNative widget trees. It provides ProviderScope, ConsumerWidget, and WidgetRef, allowing widgets to watch, read, listen to, and override standard Riverpod providers directly without platform-native code.

by Rerurate514/provider_scope · DartNative ≥ 3.0 · updated 5 days ago
Install
Free
pubspec.yaml
dependencies:
  provider_scope:
    hosted: https://dartpub.dev
    version: ^0.3.0
Weekly installs
0
Active apps
0
Rating
0.0 · 0
Open issues
0

provider_scope

Riverpod-backed ProviderScope primitives for DartNative apps.

provider_scope brings Riverpod's container model to DartNative's widget tree. It provides a DartNative ProviderScope, ConsumerWidget, and WidgetRef so app code can read and watch Riverpod providers from DartNative widgets.

The package depends on package:riverpod and re-exports its core APIs, including Provider, ProviderContainer, NotifierProvider, FutureProvider, and StreamProvider.

Features

  • Use Riverpod providers from DartNative widgets.
  • Rebuild DartNative widgets with ref.watch(provider).
  • Read providers without listening with ref.read(provider).
  • React to provider changes with ref.listen(provider, listener).
  • Imperatively subscribe with ref.listenManual(provider, listener).
  • Refresh or invalidate providers from the widget layer.
  • Pass Riverpod overrides directly to ProviderScope.
  • Access the underlying ProviderContainer when needed.

Installation

Add the package to your DartNative app:

dependencies:
  provider_scope: ^0.3.0

Then run:

dn pub get

Basic Usage

Wrap your DartNative app with ProviderScope.

import 'package:dartnative/dartnative.dart';
import 'package:provider_scope/provider_scope.dart';

import 'dartnative_plugin_registrant.dart';

final counterProvider = NotifierProvider<Counter, int>(Counter.new);

final messageProvider = Provider<String>((ref) {
  final count = ref.watch(counterProvider);
  return 'Count: $count';
});

class Counter extends Notifier<int> {
  @override
  int build() {
    return 0;
  }

  void increment() {
    state++;
  }
}

void main() {
  DartNativePluginRegistrant.registerAll();
  runApp(const ProviderScope(child: HomeScreen()));
}

class HomeScreen extends ConsumerWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    ref.listen<int>(counterProvider, (previous, next) {
      dnLog('Counter changed from ${previous ?? 0} to $next');
    });

    final message = ref.watch(messageProvider);

    return Button(
      title: message,
      onPressed: () {
        ref.read(counterProvider.notifier).increment();
      },
    );
  }
}

ref.watch(provider) subscribes the ConsumerWidget to provider changes. When the provider emits a new value, the widget rebuilds.

ref.read(provider) reads the current value without subscribing.

ref.listen(provider, listener) subscribes to provider changes for side effects such as logging, navigation, persistence, or analytics. The subscription is closed automatically when the ConsumerWidget is disposed.

ref.listenManual(provider, listener) returns a ProviderSubscription that can be paused, resumed, read, or closed manually. It is also closed automatically when the ConsumerWidget is disposed.

ref.refresh(provider) forces a provider to recompute immediately and returns the new value. ref.invalidate(provider) marks a provider or family for refresh. Use ref.exists(provider) to check whether a provider is already initialized.

Overrides

Pass Riverpod overrides directly to ProviderScope.

final apiBaseUrlProvider = Provider<String>((ref) {
  return 'https://api.example.com';
});

ProviderScope(
  overrides: [
    apiBaseUrlProvider.overrideWithValue('https://staging.example.com'),
  ],
  child: const HomeScreen(),
);

Parent Containers

You can pass a parent ProviderContainer when composing scopes:

final parent = ProviderContainer();

ProviderScope(
  parent: parent,
  child: const HomeScreen(),
);

Container Access

If you need direct access to Riverpod's container, use ProviderScope.containerOf(context).

final container = ProviderScope.containerOf(context);
final value = container.read(messageProvider);

For most UI code, prefer ref.watch(provider) and ref.read(provider) inside a ConsumerWidget.

Example

See example/lib/main.dart for a small counter app built with ProviderScope.