首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Riverpod:在onPressed中引用ref.watch早先获得的提供者是错误的吗?

Riverpod:在onPressed中引用ref.watch早先获得的提供者是错误的吗?
EN

Stack Overflow用户
提问于 2022-10-24 02:09:17
回答 3查看 38关注 0票数 1

Riverpod文档建议在回调中使用ref.read,就像按钮的onPressed一样,因为您不能在那里使用ref.watch

这样做可以吗?

代码语言:javascript
复制
build(context, ref) {
  // Use ref.watch ahead of time, because I refer to p all over 
  // the widget tree. p is a mutable ChangeNotifier
  final p = ref.watch(myProvider);

  return ElevatedButton(
    onPressed: () {
      // Refer to provider obtained via ref.watch earlier
      p.mutateSomehow(),
    },
    child: /* huge tree referring to p 20 times */
  );
}

?我在我所有的代码中都这样做,它看起来工作得很好,但是如果这个模式还好的话,似乎Riverpod只是推荐它,并且不推荐ref.read

EN

Stack Overflow用户

发布于 2022-10-24 07:02:58

我认为这样做是为了保证,我们得到了供应商的最新状态。因此,在(){}中的任何操作之前都应该使用ref.read。这样我们就不可能在将来犯错误了:)

下面是一个可能的情况的完整例子:

代码语言:javascript
复制
void main() => runApp(const ProviderScope(child: MyApp()));

final indexProvider = StateProvider<int>((ref) {
  ref.listenSelf((previous, next) {
    print(ref.controller.state);
  });
  return 0;
});

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    print('build $MyApp');

    return MaterialApp(
      home: Center(
        child: Column(
          children: const [
            SizedBox(height: 50.0),
            ButtonInternalState(),
            SizedBox(height: 50.0),
            ButtonProviderState(),
          ],
        ),
      ),
    );
  }
}

class ButtonInternalState extends ConsumerWidget {
  const ButtonInternalState({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    print('build $ButtonInternalState');

    // Once upon a time, all we had to do was read the data once and not keep track of anything
    final StateController<int> indexState = ref.read(indexProvider.state);

    return ElevatedButton(
      onPressed: () => indexState.state++,

      // It would have avoided the mistake
      // onPressed: () => ref.read(indexProvider.state).state++,

      child: Text('The state our wrong provider - ${indexState.state}'),
    );
  }
}

class ButtonProviderState extends ConsumerWidget {
  const ButtonProviderState({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    print('build $ButtonProviderState');

    final int index = ref.watch(indexProvider);

    return Column(
      children: [
        ElevatedButton(
            onPressed: () => ref.read(indexProvider.notifier).state++,
            child: Text('Here changes state the provider - $index')),
        ElevatedButton(
            onPressed: () => ref.refresh(indexProvider),
            child: const Text('Refresh our provider')),
      ],
    );
  }
}
票数 1
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74176115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档