[官文翻译]Flutter状态管理库Riverpod - 概念 - ProviderObserver

584 阅读1分钟

Riverpod的官方文档有多国语言,但是没有汉语,所以个人简单翻译了一版。

官网文档:Riverpod

GitHub:GitHub - rrousselGit/river_pod

Pub:riverpod | Dart Package (flutter-io.cn)

译时版本:riverpod 1.0.3


ProviderObserver

ProviderObserver 监听 ProviderContainer 的改变。

要使用它,需要继承 ProviderObserver 类并覆写想要使用的方法。

ProviderObserver 有三个方法:

  • didAddProvider 会在每次 provider 初始化时调用,它暴露的值是 value
  • didDisposeProvider 会在每次 provider 被销毁时调用。
  • didUpdateProvider 会在每次它们发出通知时被 provider 调用。

用法:

使用 ProviderObserver 的一个简单使用场景是通过覆写 didUpdateProvider 方法记录 provider 的变化。

// 用带 Logger 的 Riverpod 实现的计数器示例。A Counter example implemented with riverpod with Logger

class Logger extends ProviderObserver {
  @override
  void didUpdateProvider(
    ProviderBase provider,
    Object? previousValue,
    Object? newValue,
    ProviderContainer container,
  ) {
    print('''
{
  "provider": "${provider.name ?? provider.runtimeType}",
  "newValue": "$newValue"
}''');
  }
}

void main() {
  runApp(
    // 添加 ProviderScope 使用 Riverpod 能用于整个工程
    // 为 observer 列表添加 Logger
    ProviderScope(observers: [Logger()], child: const MyApp()),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: Home());
  }
}

final counterProvider = StateProvider((ref) => 0, name: 'counter');

class Home extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('Counter example')),
      body: Center(
        child: Text('$count'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => ref.read(counterProvider.notifier).state++,
        child: const Icon(Icons.add),
      ),
    );
  }
}

现在,每次 provider 的值被更新后,日志都会记录下来:

I/flutter (16783): {
I/flutter (16783):   "provider": "counter",
I/flutter (16783):   "newValue": "1"
I/flutter (16783): }

:

由于状态是可变的,如 StateController (StateProvider.state的状态) 和 ChangeNotifier,旧的值和新的值会是相同的。

因为它们引用了相同的 StateController / ChangeNotifier