Flutter 当Flitter FutureProvider解决它时导航离开';未来

Flutter 当Flitter FutureProvider解决它时导航离开';未来,flutter,dependency-injection,state,Flutter,Dependency Injection,State,我基本上是在寻找一种方法,要么开始加载数据,要么导航到登录屏幕 FutureProvider从SharedReferences获取其价值。默认主屏幕只是一个带有微调器的徽标 如果userID解析为null,则应用程序应导航到登录屏幕,否则应调用将开始加载数据的方法,然后在完成时导航到主页 这可以通过FutureProvider实现吗 我将其添加到页面构建中,以确保页面小部件将订阅提供商: 小部件构建(构建上下文){ userInfo=Provider.of(上下文); 打印($userInfo建

我基本上是在寻找一种方法,要么开始加载数据,要么导航到登录屏幕

FutureProvider从SharedReferences获取其价值。默认主屏幕只是一个带有微调器的徽标

如果userID解析为null,则应用程序应导航到登录屏幕,否则应调用将开始加载数据的方法,然后在完成时导航到主页

这可以通过FutureProvider实现吗

我将其添加到页面构建中,以确保页面小部件将订阅提供商:

小部件构建(构建上下文){
userInfo=Provider.of(上下文);
打印($userInfo建筑);
返回带有LoadingIndicator()的页面;
....
我将其添加到didChangeDependencies以响应更改:

@覆盖
void didChangeDependencies(){
打印('Deps changed:$userInfo');
super.didChangeDependencies();
//userInfo=Provider.of(context);//已在生成,无法执行此操作。
//打印('And now:$userInfo');
if(userInfo==null)返回;
if(userInfo.userId!=null){
startUp();//用户登录时运行
}否则{
tryLogin();//导航到登录
}
}
由于无法在initState中使用Provider.of,我添加了一个PostFrameCallback

void postFrame(BuildContext){
打印('PostFrame…');
userInfo=Provider.of(上下文);
}
Main非常简单-它现在只需要使用一个FutureProvider来设置MultiProvider

类MyApp扩展了无状态小部件{
未来的getUserInfo()异步{
字符串令牌=等待UserPrefs.token;
返回UserInfo.fromToken(
代币
);
}
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“应用程序一”,
主题:主题数据(
原色样本:颜色。紫色,
),
主页:MultiProvider(
提供者:[FutureProvider(生成器:(\u)=>getUserInfo())],
子项:加载屏幕(),
),
);
}
}
现在的问题是,从print语句中我可以看到,“didChangeDependencies”被调用了两次,但是userInfo的值始终为null,即使build()最终获得了userInfo的实例,这一点在build()方法中的print语句中很明显


我猜我可以在构建方法中添加一些逻辑,但这与我的感觉不符,因为这是一个错误的地方…也许它没有我想的那么糟糕?

我认为这在概念上是错误的方法

在我的例子中,我想使用FutureProvider从一个异步函数获取结果,该函数使用SharedReferences创建一个“Config”对象。FutureProvider将允许应用程序的其余部分访问从sharepreferences获得的用户配置设置

在我看来,这仍然是一种有效的方法。但从应用程序流的角度来看,这存在一些问题

主要是来自共享首选项的值包括登录的用户会话令牌和用户名

该应用程序首先显示一个带有圆形进度条的加载屏幕。然后,该应用程序读取共享首选项并联机连接以检查会话是否有效。如果没有会话,或者会话无效,则该应用程序导航到登录名“wizzard”它会询问用户名,然后在下一页上询问密码,然后在下一页上询问双因素登录。之后,它会导航到登录页。如果加载页找到有效会话,则会跳过登录wizzard

问题是,应用程序状态和应用程序流这两件事在本质上是不同的。应用程序流可以导致在应用程序状态中存储更改,但应用程序状态不应该影响应用程序流,至少在概念上不会以这种方式

实际上,我不认为从FutureProvider的构建函数调用Navigator.push()是有效的,即使上下文是可用的。我可能错了,但我觉得流动的方法更灵活

@覆盖
void initState(){
super.initState();
_loadSharedPrefs()。然后((){
如果(this.session.isValid())\u navToLandingPage();
else_navToLoginStepOne();
}
}

我愿意接受更好的建议/指导

您是否尝试过致电userInfo=Provider.of(上下文);在didChangeDependencies中?是的,您不能这样做。这会导致一个错误,因为构建已经在进行中。我认为问题在于提供商只想构建小部件,而不是控制应用程序的流程。因此,现在在initState的这一页上,我添加了一个对异步函数的调用,该函数将等待SharedReferences,然后导航删除或启动数据加载过程。