基本的に私がやろうとしていることは次のとおりです。モバイル アプリが起動すると、ローカル データベースにユーザー エントリが存在するかどうかがチェックされます。チェック中、今のところ空の黄色の画面が表示されます。これは、読み込み中/チェックがまだ完了していないことを示しています。完了すると、ユーザー データに基づいて画面が表示されます。そのために、Riverpod パッケージを使用して StateNotifierProvider を作成しました。
class ChangeScreenNotifier extends StateNotifier<Screen> {
ChangeScreenNotifier() : super(null);
void changeTo(Screen screen) {
state = screen;
}
}
final initialScreenStateNotifierProvider = StateNotifierProvider<ChangeScreenNotifier>((ref) => ChangeScreenNotifier());
初期状態は null ですが、画面列挙型 (SignInScreen、EmailVerificationScreen など) の値に変更することもできます。
今、アプリを起動すると、明らかに状態が null なので、黄色の画面を表示しています。検索が完了すると、状態は null からユーザー データに基づく値に変わります。したがって、状態がnullかどうかを確認するifステートメントを前に作成して、黄色のロード画面の後に表示される初期画面がすでにあるかどうかを確認して設定しました。
final initialScreen = watch(initialScreenStateNotifierProvider.state);
return MaterialApp(
debugShowCheckedModeBanner: false,
supportedLocales: context.supportedLocales,
localizationsDelegates: context.localizationDelegates,
navigatorKey: Routes.sailor.navigatorKey,
onGenerateRoute: Routes.sailor.generator(),
home: StreamListener(
stream: localDatabase.streamLocalUser().map((localUser) => UserModel.fromLocalUser(localUser)),
onData: (UserModel userModel) {
print(initialScreen);
if (initialScreen == null) {
context.read(initialScreenStateNotifierProvider).changeTo(userModel == null ? Screen.OnboardingScreen : !userModel.isEmailVerified ? Screen.EmailVerificationScreen : Screen.HomeScreen);
}
print(initialScreen);
},
child: initialScreen == null ? Container(color: Colors.yellow) : initialScreen.screen
)
);
しかし、ユーザーを挿入してユーザー ストリームが再び実行されると、if ステートメント内で再度実行され、状態が再び null であることがわかります。さまざまな場所で状態を何度も確認した後、常に null と表示されます。
だから私の質問は次のとおりです:なぜそれは常にnullであり、渡した画面を永続化しないのですか?
注: 黄色の画面の後、本来の OnboardingScreen が表示されるので、StateNotifier への画面の受け渡しが機能することがわかります。しかし、なぜすぐにnullに戻るのかという疑問に関しては、それは私には役に立ちません。