如何在 riverpod 中确定提供者的范围?

How to scope a provider in riverpod?

我开始使用 riverpod and I'm trying to migrate my existing code which was using provider

使用 providerProvider 被限定在小部件树中。只有 Provider 小部件的子级可以访问其模型。

它在 riverpod 的文档中说:

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.

provider 包是 simplification/wrapper/API 大约 InheritedWidget 秒,所以我想 provider 的可能也可能 riverpod

但我无法找出如何去做。


这是我尝试迁移的一个小例子。

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}'),
            ],
          );
        },
      ),
    );
  }
}

只要有 MyWidget 小部件,子小部件就可以访问 unique/scoped 模型 Counter

ProviderScope 内部是一个 InheritedWidget,因此您可以像 Provider 一样使用多个 ProviderScope。请查看这张票中Remi的代码link.

或者您可以根据需要使用 .family 和 .autoDispose。

范围提供程序是通过 ProviderScope

完成的

你可以这样做:

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


// in some widget:

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

虽然如果你能避免范围界定,那就这样做吧。通常不推荐并应避免提供范围界定提供程序,因为这是相当先进的。

如果您使用范围提供程序以便在用户离开页面时销毁状态,则更简单的解决方案是使用 autoDispose:

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

// No longer needed to scope the provider