You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Riverpod的Provider获取Listenable以适配go_router的refreshListenable

实现方案

最简单的实现方式(无需额外合并Provider)

推荐直接将GoRouter本身声明为Riverpod Provider,借助ref.listen方法监听你的两个目标Provider,用内置的ValueNotifier作为refreshListenable即可,示例代码如下:

// 你的原有Provider示例,替换成自己的类型和实现
final firstProvider = Provider<FirstState>((ref) => FirstState());
final secondStreamProvider = StreamProvider<SecondState>((ref) => Stream.value(SecondState()));

// GoRouter 声明为Provider
final goRouterProvider = Provider<GoRouter>((ref) {
  // 空的ValueNotifier,本身实现了Listenable接口,专门用来触发路由刷新
  final refreshTrigger = ValueNotifier<Object?>(null);

  // 监听第一个Provider变化,每次更新都触发刷新
  ref.listen<FirstState>(firstProvider, (previous, next) {
    refreshTrigger.value = Object();
  });

  // 监听第二个StreamProvider变化,每次更新都触发刷新
  ref.listen<AsyncValue<SecondState>>(secondStreamProvider, (previous, next) {
    refreshTrigger.value = Object();
  });

  return GoRouter(
    // 传入我们创建的触发器即可
    refreshListenable: refreshTrigger,
    // 你的路由配置
    routes: [
      // ...你的路由列表
    ],
    redirect: (context, state) {
      // 重定向逻辑可以直接通过ref.read读取两个Provider的最新状态
      final firstState = ref.read(firstProvider);
      final secondState = ref.read(secondStreamProvider).valueOrNull;
      
      // 示例:根据状态判断重定向目标
      if (secondState == null) return '/loading';
      if (!firstState.isLogin) return '/login';
      return null;
    },
  );
});

单独封装合并后的Listenable Provider

如果你需要将刷新逻辑抽离复用,可以单独声明一个提供合并Listenable的Provider:

final routerRefreshListenable = Provider<Listenable>((ref) {
  final trigger = ValueNotifier<Object?>(null);
  // 统一监听所有需要触发路由刷新的Provider
  ref.listen(firstProvider, (_, __) => trigger.value = Object());
  ref.listen(secondStreamProvider, (_, __) => trigger.value = Object());
  return trigger;
});

// GoRouter里直接引用即可
final goRouterProvider = Provider<GoRouter>((ref) {
  return GoRouter(
    refreshListenable: ref.watch(routerRefreshListenable),
    // 剩余配置
  );
});

注意事项

  • 这种方式属于Riverpod官方推荐的合法用法,不会违背框架设计原则,完全兼容现有基于Riverpod开发的项目
  • 重定向逻辑里读取Provider状态用ref.read即可,不需要用ref.watch,因为我们已经通过ref.listen监听了状态变化,每次状态更新都会触发重定向逻辑重新执行

内容的提问来源于stack exchange,提问作者imi kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:06:06