【问题标题】:How can I react to a riverpod FutureProvider by using ref.listen?如何使用 ref.listen 对riverpod FutureProvider 做出反应?
【发布时间】:2022-07-28 17:08:31
【问题描述】:
final nextRouteProvider = FutureProvider<String>((ref) async {
  await Future.delayed(const Duration(seconds: 3));
  bool isAppFreshInstall = StorageManager.instance.isAppFreshInstall();
  if (isAppFreshInstall) {
    return AppRouter.onBoardingPath;
  } else {
    return AppRouter.loginPath;
  }
});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    ref.listen<Future<String>>(nextRouteProvider.future, (_, Future<String> path) async {
      context.go(await path);
    });

    return SplashScreen();
  }

上述逻辑不起作用,但它与 StateNotifierProvider 配合得很好。

class RootViewNotifier extends StateNotifier<String> {
  RootViewNotifier() : super('/') {
    decideRootView();
  }

  void decideRootView() async {
    await Future.delayed(const Duration(seconds: 3));
    var storageManager = StorageManager.instance;
    if (storageManager.isAppFreshInstall()) {
      state = AppRouter.onBoardingPath;
    } else {
      state = AppRouter.loginPath;
    }
  }
}

final rootViewNotifierProvider =
    StateNotifierProvider<RootViewNotifier, String>(() => RootViewNotifier());

@override
  Widget build(BuildContext context, WidgetRef ref) {
    ref.listen<String>(rootViewNotifierProvider, (, String path) {
      context.go(path);
    });

   return SplashScreen(); 
 }

但更好的方法是使用在这种情况下不起作用的 FutureProvider。那么我的代码有什么问题。如何使用具有相同逻辑的 FutureProvider?

【问题讨论】:

    标签: flutter riverpod


    【解决方案1】:

    收听nextRouteProvider 而不是nextRouteProvider.future

    像这样:

    ref.listen(
      nextRouteProvider,
      (AsyncValue<String>? _, AsyncValue<String> next) {
          context.go(next.asData!.value);
       },
    );
    

    【讨论】:

      【解决方案2】:

      未来的提供者不打算用于通知更改。它仅用于通知数据何时从异步源准备好。相反,要获得通知,唯一的解决方案是通知提供程序,并将其与异步数据一起使用:

      Future<int> fetch() aynsc => 42;
      class Whatever extends StateNotifier<AsyncValue<int>> {    
          Whatever(): super(const AsyncValue.loading()) {        
              _fetch();
          }
          Future<void> _fetch() async {
              state = const AsyncValue.loading();
              state = await AsyncValue.guard(() => fetch());    
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-11
        • 2021-12-24
        • 1970-01-01
        • 2022-10-19
        • 2021-03-23
        • 2022-12-14
        • 2022-08-14
        • 1970-01-01
        相关资源
        最近更新 更多