[英]How can I react to a riverpod FutureProvider by using ref.listen?
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?
聽nextRouteProvider
而不是nextRouteProvider.future
像這樣:
ref.listen(
nextRouteProvider,
(AsyncValue<String>? _, AsyncValue<String> next) {
context.go(next.asData!.value);
},
);
未來的提供者不打算用於通知更改。 它僅用於通知數據何時從異步源准備好。 相反,要獲得通知,唯一的解決方案是通知提供程序,並將其與異步數據一起使用:
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());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.