Valentin Vignal
Valentin Vignal

Reputation: 8202

How to scope a provider in riverpod?

I'm starting to use riverpod and I'm trying to migrate my existing code which was using provider.

With provider, the Providers were scoped in the widget tree. Only the children of the Provider widget could access its model.

It says in the riverpod's doc:

Allows easily accessing that state in multiple locations. Providers are a complete replacement for patterns like Singletons, Service Locators, Dependency Injection or InheritedWidgets.

* "Providers" here refers to the Provider class of the package riverpod.

And the provider package was a simplification/wrapper/API around InheritedWidgets so I guess what was possible with provider is also possible with riverpod.

But I cannot manage to find out how to do it.


Here is a small example of what I am trying to migrate.

class Counter extends ValueNotifier<int> {
  Counter(): super(0);
}


class MyWidget extends StatelessWidget {
  const MyWidget();
  
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Counter>(
      create: (_) => Counter();
      child: Builder(
        builder: (context) {
          return Row(
            children: [
              IconButton(
                onPressed: () {
                  context.read<Counter>().value++;
                }, 
                icon: Icon(Icons.add),
              ),
              Text('Count: ${context.watch<Counter>().value}'),
            ],
          );
        },
      ),
    );
  }
}

Wherever there is a MyWidget widget, the sub-widget has access to a unique/scoped model Counter.

Upvotes: 5

Views: 7585

Answers (2)

R&#233;mi Rousselet
R&#233;mi Rousselet

Reputation: 277037

Scoping providers is done through ProviderScope

You can do:

final provider = ChangeNotifierProvider<Counter>((ref) => throw UnimplementedError());


// in some widget:

return ProviderScope(
  overrides: [
    provider.overrideWithProvider(
      ChangeNotifierProvider((ref) => Counter());
    ),
  ],
)

Although if you can avoid scoping, do so. Scoping providers is generally not recommended and should be avoided as that's fairly advanced.

If you're using a scoped provider so that the state is destroyed when the user leaves the page, a much simpler solution is to use autoDispose:

final provider = ChangeNotifierProvider.autoDispose<Counter>((ref) => Counter());

// No longer needed to scope the provider

Upvotes: 7

dante
dante

Reputation: 1254

Inside ProviderScope is an InheritedWidget, so you can you multiple ProviderScope just like Provider. Please checkout the code of Remi in this ticket link.

Or you can use .family and .autoDispose for your purpose.

Upvotes: 0

Related Questions