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());
}
}
不再建议将 StateNotifier 与 Riverpod 一起使用。更正确的示例是使用 AsyncNotifier,它提供 AsyncValue 以及 ref.watch 或 ref.listen 的用法。下面的示例和更多信息请参见 从 StateNotifier 迁移 Riverpod 文档
Future<int> fetch() async => 42;
class MyAsyncNotifier extends AsyncNotifier<int> {
static final provider =
AsyncNotifierProvider<MyAsyncNotifier, int>(MyAsyncNotifier);
@override
FutureOr<int> build() async {
return fetch();
}
}
然后您可以使用以下代码在小部件中收听此通知程序。
class MyWidget extends ConsumerStatefulWidget {
const MyWidget({super.key});
@override
ConsumerState< MyWidget > createState() => _ MyWidgetState();
}
class _MyWidgetState extends ConsumerState<MyWidget>{
@override
Widget build(BuildContext context) {
ref.listen(MyAsyncNotifier.provider, (previous, next){
next.whenData((value) {
//do something with value
}
});
}
}