Flutter Riverpod ref.read() vs ref.listen() vs ref.watch()

Vra*_*hah 19 dart flutter riverpod

阅读文档后,它没有很好地解释什么是ref.read()ref.watch()、 和ref.listen()

我的问题如下:

  • 这些功能的目的和区别是什么?
  • 哪些地方可以使用这些功能,哪些地方不能使用这些功能?
  • 我什么时候应该使用这些功能?

Jos*_*eve 37

这些功能的目的和区别是什么?

\n

读()

\n

用于read仅获取提供者的值一次(一次性读取)

\n

手表()

\n

用于watch第一次和每次值更改时获取提供程序的值(就像您订阅提供程序一样,因此只要有更改,您就会收到通知)

\n

听()

\n

listen类似于watch。主要区别在于返回类型。\nwatch直接返回新值,listen返回 avoid但通过回调提供对新值和旧值的访问(请参阅下面的示例)

\n

哪些地方可以使用这些功能,哪些地方不能使用这些功能?

\n

您可以read在诸如initState、 回调之类的onPressed地方使用watch,并且listen不应异步调用,例如在onPressedElevatedButton 的内部。initState它也不应该在内部和其他状态生命周期中使用。

\n

正如 Kaan Taha K\xc3\xb6ken 指出的:

\n
\n

避免使用 [read] 创建值永不改变的小部件,并考虑使用 [Provider] 或select过滤不需要的重建。

\n
\n

我什么时候应该使用这些功能?

\n

读()

\n

read当您只想对提供者进行一次赋值时使用。

\n

手表()

\n

watch当您想要始终获得该值时使用。

\n

示例:计数器应用程序StateProvider

\n
final counterProvider = StateProvider((ref) => 0);\nclass HomePage extends ConsumerWidget {\n  const HomePage({Key? key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context, WidgetRef ref) {\n    final counter = ref.watch(counterProvider);\n    ref.listen(\n      counterProvider,\n      (previous, next) {\n        print("The new value is $next");\n        if (next == 5) {\n          print("I just reached 5");\n        }\n      },\n    );\n    return Scaffold(\n      body: Center(\n        child: Text(\n          counter.toString(),\n        ),\n      ),\n      floatingActionButton: FloatingActionButton(\n        onPressed: () {\n          ref.read(counterProvider.state).state += 1;\n        },\n      ),\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

watch上面的示例显示了,read和的用法listen

\n
    \n
  • 我们正在watch计算该counter值,以便在发生更改时它会在 UI 中更新。
  • \n
  • 我们listencounter打印更新后的值并I've reached 5在它为 5 时打印。
  • \n
  • 为了增加该值,我们read提供程序状态并在按下1时添加。FloatingActionButton
  • \n
\n