Flutter Riverpod ref.read() vs ref.listen() vs ref.watch()
Flutter Riverpod ref.read() vs ref.listen() vs ref.watch()
看完了documentation,没有很好的解释什么是ref.read()
、ref.watch()
、ref.listen()
我的问题如下:
- 这些函数的作用和区别是什么?
- 我可以在哪些地方使用这些功能?
- 我什么时候应该使用这些功能?
Riverpod 是 Provider 包的完全重写
我还没有用过 Riverpod
但作为提供者的经验,我将分享一些细节
read()
用于听一次;它可能是函数或变量
watch()
是为了多听时间,即听真话;所以当数据发生变化时将被监听并采用新值
lisen()
watch 和 lisen 之间的主要区别在于,如果侦听的提供程序更改,则不会重建 widget/provider,而是使用 ref.listen 调用自定义函数。
这对于在发生特定更改时执行操作很有用,例如在发生错误时显示快餐栏。
了解更多信息
take a look at this
这些函数的作用和区别是什么?
阅读()
使用 read
获取值 of/in 提供程序一次(one-time 读取)
观看()
第一次使用 watch
获取值 of/in 提供程序,每次值更改时(就像订阅提供程序一样查看它,因此您会在任何时候收到通知一个变化)
听()
listen
类似于 watch
。主要区别在于 return 类型。
watch
return 直接使用新值,listen
return 使用 void
但是可以通过回调访问新值和旧值(参见下面的示例)
我可以在哪些地方使用这些功能?
你可以在 initState
这样的地方使用 read
,像 onPressed
这样的回调等等。 watch
和 listen
不应该被异步调用,比如里面ElevatedButton 的 onPressed
。也不应在 initState
和其他州 life-cycles.
中使用
正如 Kaan Taha Köken 指出的那样:
AVOID using [read] for creating widgets with a value that never changes and CONSIDER using [Provider] or select
for filtering unwanted rebuilds.
我什么时候应该使用这些功能?
阅读()
如果您只想提供程序的值一次,请使用 read
。
观看()
如果您希望始终获取值,请使用 watch
。
示例:具有 StateProvider
的计数器应用
final counterProvider = StateProvider((ref) => 0);
class HomePage extends ConsumerWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final counter = ref.watch(counterProvider);
ref.listen(
counterProvider,
(previous, next) {
print("The new value is $next");
if (next == 5) {
print("I just reached 5");
}
},
);
return Scaffold(
body: Center(
child: Text(
counter.toString(),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
ref.read(counterProvider.state).state += 1;
},
),
);
}
}
上面的示例显示了 watch
、read
和 listen
的用法。
- 我们正在
watch
计算 counter
值,因此只要有变化,它就会在 UI 中更新。
- 我们
listen
正在 counter
打印更新后的值并在 I've reached 5
为 5 时打印。
- 为了增加值,我们
read
提供者状态并在按下 FloatingActionButton
时添加 1
。
看完了documentation,没有很好的解释什么是ref.read()
、ref.watch()
、ref.listen()
我的问题如下:
- 这些函数的作用和区别是什么?
- 我可以在哪些地方使用这些功能?
- 我什么时候应该使用这些功能?
Riverpod 是 Provider 包的完全重写 我还没有用过 Riverpod 但作为提供者的经验,我将分享一些细节
read()
用于听一次;它可能是函数或变量
watch()
是为了多听时间,即听真话;所以当数据发生变化时将被监听并采用新值
lisen()
watch 和 lisen 之间的主要区别在于,如果侦听的提供程序更改,则不会重建 widget/provider,而是使用 ref.listen 调用自定义函数。
这对于在发生特定更改时执行操作很有用,例如在发生错误时显示快餐栏。
了解更多信息 take a look at this
这些函数的作用和区别是什么?
阅读()
使用 read
获取值 of/in 提供程序一次(one-time 读取)
观看()
第一次使用 watch
获取值 of/in 提供程序,每次值更改时(就像订阅提供程序一样查看它,因此您会在任何时候收到通知一个变化)
听()
listen
类似于 watch
。主要区别在于 return 类型。
watch
return 直接使用新值,listen
return 使用 void
但是可以通过回调访问新值和旧值(参见下面的示例)
我可以在哪些地方使用这些功能?
你可以在 initState
这样的地方使用 read
,像 onPressed
这样的回调等等。 watch
和 listen
不应该被异步调用,比如里面ElevatedButton 的 onPressed
。也不应在 initState
和其他州 life-cycles.
正如 Kaan Taha Köken 指出的那样:
AVOID using [read] for creating widgets with a value that never changes and CONSIDER using [Provider] or
select
for filtering unwanted rebuilds.
我什么时候应该使用这些功能?
阅读()
如果您只想提供程序的值一次,请使用 read
。
观看()
如果您希望始终获取值,请使用 watch
。
示例:具有 StateProvider
的计数器应用
final counterProvider = StateProvider((ref) => 0);
class HomePage extends ConsumerWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final counter = ref.watch(counterProvider);
ref.listen(
counterProvider,
(previous, next) {
print("The new value is $next");
if (next == 5) {
print("I just reached 5");
}
},
);
return Scaffold(
body: Center(
child: Text(
counter.toString(),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
ref.read(counterProvider.state).state += 1;
},
),
);
}
}
上面的示例显示了 watch
、read
和 listen
的用法。
- 我们正在
watch
计算counter
值,因此只要有变化,它就会在 UI 中更新。 - 我们
listen
正在counter
打印更新后的值并在I've reached 5
为 5 时打印。 - 为了增加值,我们
read
提供者状态并在按下FloatingActionButton
时添加1
。