У меня проблема с трепетом при попытке прочитать данные из локального хранилища при загрузке приложения.
У меня есть унаследованный виджет, который содержит информацию для аутентификации текущего пользователя.Когда приложение загружается, я хочу заглянуть в локальное хранилище для токенов сессии.Если токены сессии существуют, я бы хотел обновить унаследованный виджет этой информацией.
Мои экраны динамические.Если он знает, что пользователь прошел проверку подлинности, он выводит их на запрошенный экран, в противном случае он выводит их на экран регистрации.
Проблема, с которой я сталкиваюсь, заключается в том, что я не могу обновить состояние унаследованного виджета из initState()
метод из виджета, который зависит от унаследованного виджета (виджет Мой маршрутизатор)
Как я могу читать из локального хранилища, когда приложение загружает и обновляет унаследованный виджет?
Ошибка при запуске приложения:
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building _InheritedAuthContainer:
flutter: inheritFromWidgetOfExactType(_InheritedAuthContainer) or inheritFromElement() was called before
flutter: RootState.initState() completed.
flutter: When an inherited widget changes, for example if the value of Theme.of() changes, its dependent
flutter: widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor
flutter: or an initState() method, then the rebuilt dependent widget will not reflect the changes in the
flutter: inherited widget.
flutter: Typically references to inherited widgets should occur in widget build() methods. Alternatively,
flutter: initialization based on inherited widgets can be placed in the didChangeDependencies method, which
flutter: is called after initState and whenever the dependencies change thereafter.
Виджет маршрутизатора (Root)
class Root extends StatefulWidget {
@override
State createState() => RootState();
}
class RootState extends State<Root> {
static Map<String, Widget> routeTable = {Constants.HOME: Home()};
bool loaded = false;
bool authenticated = false;
@override
void initState() {
super.initState();
if (!loaded) {
AuthContainerState data = AuthContainer.of(context);
data.isAuthenticated().then((authenticated) {
setState(() {
authenticated = authenticated;
loaded = true;
});
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
onGenerateRoute: (routeSettings) {
WidgetBuilder screen;
if (loaded) {
if (authenticated) {
screen = (context) => SafeArea(
child: Material(
type: MaterialType.transparency,
child: routeTable[routeSettings.name]));
} else {
screen = (conext) => SafeArea(
child: Material(
type: MaterialType.transparency, child: Register()));
}
} else {
screen = (context) => new Container();
}
return new MaterialPageRoute(
builder: screen,
settings: routeSettings,
);
});
}
}
Унаследованный метод виджета, который проверяет подлинность и обновляет себя, который запускает повторное отображение моего виджета маршрутизатора
Future<bool> isAuthenticated() async {
if (user == null) {
final storage = new FlutterSecureStorage();
List results = await Future.wait([
storage.read(key: 'idToken'),
storage.read(key: 'accessToken'),
storage.read(key: 'refreshToken'),
storage.read(key: 'firstName'),
storage.read(key: 'lastName'),
storage.read(key: 'email')
]);
if (results != null && results[0] != null && results[1] != null && results[2] != null) {
//triggers a set state on this widget
updateUserInfo(
identityToken: results[0],
accessToken: results[1],
refreshToken: results[2],
firstName: results[3],
lastName: results[4],
email: results[5]
);
}
}
return user != null && (JWT.isActive(user.identityToken) || JWT.isActive(user.refreshToken));
}
Main
void main() => runApp(
EnvironmentContainer(
baseUrl: DEV_API_BASE_URL,
child: AuthContainer(
child: Root()
)
)
);
Как правильно проверить локальное хранилище при загрузке приложения и обновить унаследованный виджет, содержащий эту информацию?