问题描述
我编写了一些代码来为 ApiService
提供 StateNotifier
。 ApiService
依赖于 authenticatorclient
- 必须异步创建身份验证客户端,因为它使用共享首选项来获取令牌。
我只是想弄清楚他们的写作方式是否更优雅。基本上,当服务 apiService 被注入到 StateNotifier 时,它可能是可以为空的......对我来说这有点代码味道。
简而言之,这就是我在做什么...
使用 FutureProvider
实例化 RestClient
和 dio
authenticatorClient = FutureProvider<RestClient>((ref) async {
final prefs = await SharedPreferences.getInstance();
final dio = dio();
...
return RestClient(dio);
}
然后我观看并使用 MaybeWhen 返回服务
final clientCreatorWatchProvider = Provider<ApiService?>((ref) => ref
.watch(authenticatorClient)
.whenData((value) => ApiService(value))
.maybeWhen(
data: (service) => service,orElse: () => null,));
所以我不喜欢的一点是 orElse 返回 null
然后我的 StateNotifier
正在观看...
final AppState = StateNotifierProvider<AppNotifier,String>(
(ref) => AppNotifier(ref.watch(clientCreatorWatchProvider)));
class AppNotifier extends StateNotifier<String> {
final ApiService? apiService;
AppNotifier(this.apiService) : super("loading") {
init();
}
...
}
对上述方法有什么想法吗?
谢谢
解决方法
解决此问题的一种方法是在提供程序之外初始化 SharedPreferences
。然后,您可以使用 ProviderScope
覆盖同步提供程序,从而无需使用 AsyncValue
。
初始化应用时,请执行以下操作:
final sharedPreferences = Provider<SharedPreferences>((_) => throw UnimplementedError());
Future<void> main() async {
final sharedPrefs = await SharedPreferences.getInstance();
runApp(
ProviderScope(
overrides: [
sharedPreferences.overrideWithValue(sharedPrefs),],child: MyApp(),),);
}
现在你可以像这样编写你的提供者:
final authenticatorClient = Provider<RestClient>((ref) {
final prefs = ref.watch(sharedPreferences);
final dio = Dio();
...
return RestClient(dio);
}
final clientCreatorWatchProvider = Provider<ApiService>((ref) {
final authClient = ref.watch(authenticatorClient);
return ApiService(authClient);
});