Flutter 导致多个HTTP重新请求的颤振状态窗口小部件

Flutter 导致多个HTTP重新请求的颤振状态窗口小部件,flutter,Flutter,这可能是由于我正在做或忘记做的蠢事造成的。 下面是颤振的完整工作代码示例(截至2019年12月5日),以及重现此问题的HTTP echo服务器(httpbin) 运行httpbin: docker run -p 1234:80 kennethreitz/httpbin 然后将代码加载到新的颤振应用程序中。 在新加载的应用程序上,单击抽屉中的Route a,您将在console中打印以下内容: flutter: Loaded <RouteA> (Stateful) flutter:

这可能是由于我正在做或忘记做的蠢事造成的。 下面是颤振的完整工作代码示例(截至2019年12月5日),以及重现此问题的HTTP echo服务器(httpbin)

运行httpbin:

docker run -p 1234:80 kennethreitz/httpbin
然后将代码加载到新的颤振应用程序中。 在新加载的应用程序上,单击抽屉中的Route a,您将在console中打印以下内容:

flutter: Loaded <RouteA> (Stateful)
flutter: Got data from Route A 1 times.
颤振:加载(有状态)
颤振:从路线A获取数据1次。
单击路线B,您将获得:

flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 1 times.
flutter: Loaded <RouteA> (Stateful)
flutter: Got data from Route A 2 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 2 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Loaded <RouteA> (Stateful)
flutter: Got data from Route A 3 times.
flutter: Got data from Route B 3 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 4 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Loaded <RouteA> (Stateful)
flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 5 times.
flutter: Got data from Route B 6 times.
flutter: Got data from Route A 4 times.
颤振:加载(有状态)
颤振:从路线B获得数据1次。
颤振:加载(有状态)
颤振:从路线A获得数据2次。
(它重新加载路由A,该路由执行另一个HTTP请求)

再次加载路线B,您将获得:

flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 1 times.
flutter: Loaded <RouteA> (Stateful)
flutter: Got data from Route A 2 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 2 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Loaded <RouteA> (Stateful)
flutter: Got data from Route A 3 times.
flutter: Got data from Route B 3 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 4 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Loaded <RouteA> (Stateful)
flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 5 times.
flutter: Got data from Route B 6 times.
flutter: Got data from Route A 4 times.
颤振:加载(有状态)
颤振:从路线B获得数据2次。
颤振:加载(有状态)
颤振:加载(有状态)
颤振:从路线A获得数据3次。
颤振:从路线B获得数据3次。
另一次装载路线B,您将获得:

flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 1 times.
flutter: Loaded <RouteA> (Stateful)
flutter: Got data from Route A 2 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 2 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Loaded <RouteA> (Stateful)
flutter: Got data from Route A 3 times.
flutter: Got data from Route B 3 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 4 times.
flutter: Loaded <RouteB> (Stateful)
flutter: Loaded <RouteA> (Stateful)
flutter: Loaded <RouteB> (Stateful)
flutter: Got data from Route B 5 times.
flutter: Got data from Route B 6 times.
flutter: Got data from Route A 4 times.
颤振:加载(有状态)
颤振:从路线B获取数据4次。
颤振:加载(有状态)
颤振:加载(有状态)
颤振:加载(有状态)
颤振:从路线B获得数据5次。
颤振:从路线B获取数据6次。
颤振:从路线A获取数据4次。
这些加载中的每一个都对应一个HTTP请求,因此,如果应用程序已打开足够长的时间,它可能会对单个有状态小部件加载发出100个HTTP请求

请注意,如果加载Route C(无状态小部件),它只加载一次

这显然与StatefulWidgets的重新加载方式有关,但我陷入困境,无法在网上找到类似问题的帖子

弗利特为什么要这么做?如何使其表现为HTTP请求的无状态小部件?

请参见下面的代码示例

/*
*使用StatefulWidget的怪异HTTP行为的颤振代码
*
*确保您还使用以下命令在本地运行httpbin:
*
*docker run-p 1234:80 kennethreitz/httpbin
*/
进口“包装:颤振/材料.省道”;
将“package:http/http.dart”导入为http;
int routeaquerys=0;
int routebquerys=0;
int ROUTECQUERES=0;
void main(){
runApp(HttpDebug());
}
类HttpDebug扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“HomeDebug”,
home:HomeDebug(),
);
}
}
类HomeDebug扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(标题:Text('Home')),
抽屉:_抽屉(),
正文:居中(子项:文本(“主”),
);
}
}
类RouteA扩展了StatefulWidget{
@凌驾
_RouteState createState()=>\u RouteState();
}
类_RouteState扩展状态{
@凌驾
小部件构建(构建上下文){
打印(“已加载(有状态)”;
返回脚手架(
appBar:appBar(标题:文本('Route A')),
抽屉:_抽屉(),
正文:未来建设者(
未来:fetchRoute('routeA'),
生成器:(BuildContext上下文,异步快照){
if(snapshot.hasData){
返回文本('RouteA Data:${snapshot.Data}');
}else if(snapshot.hasrerror){
返回文本('Error:${snapshot.Error}');
}否则{
返回文本(“加载”);
}
},
),
);
}
}
类RouteB扩展了StatefulWidget{
@凌驾
_RouteBState createState()=>\u RouteBState();
}
类_RouteBState扩展状态{
@凌驾
小部件构建(构建上下文){
打印(“已加载(有状态)”;
返回脚手架(
appBar:appBar(标题:文本('Route B')),
抽屉:_抽屉(),
正文:未来建设者(
future:fetchRoute('routeB'),
生成器:(BuildContext上下文,异步快照){
if(snapshot.hasData){
返回文本('RouteB数据:${snapshot.Data}');
}else if(snapshot.hasrerror){
返回文本('Error:${snapshot.Error}');
}否则{
返回文本(“加载”);
}
},
),
);
}
}
类RouteC扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
打印(“已加载(无状态)”;
返回脚手架(
appBar:appBar(标题:文本('Route C')),
抽屉:_抽屉(),
正文:未来建设者(
未来:fetchRoute('routeC'),
生成器:(BuildContext上下文,异步快照){
if(snapshot.hasData){
返回文本('RouteC数据:${snapshot.Data}');
}else if(snapshot.hasrerror){
返回文本('Error:${snapshot.Error}');
}否则{
返回文本(“加载”);
}
},
),
);
}
}
类_抽屉扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
回程抽屉(
子:ListView(
儿童:[
列表砖(
标题:文本(“主页”),
onTap:()=>Navigator.push(
上下文
MaterialPage路由(生成器:(上下文)=>HomeDebug()),
),
),
列表砖(
标题:文本(“路线A”),
onTap:()=>Navigator.push(
上下文
MaterialPage路由(生成器:(上下文)=>RouteA()),
),
),
列表砖(
标题:文本(“路线B”),
onTap:()=>Navigator.push(
上下文
MaterialPage路由(生成器:(上下文)=>RouteB()),
),
),
列表砖(
标题:文本(“路线C”),
onTap:()=>Navigator.push(
上下文
MaterialPage路由(生成器:(上下文)=>RouteC()),
),
),
],
)
);
}
}
未来获取路由(字符串路由)异步{
地图路线={
"路由":200