Flutter 使用带有 setState 更新的 StreamBuilder
Flutter using StreamBuilder with setState updates
我在构建方法中使用 StreamBuilder 从 firestore 检索用户信息,并在它显示 Listview.builder 后立即检索。
检索到用户信息后,我使用用户 ID 调用另一个 API 来检索我想在列表中显示的其他一些信息。这给了我每个用户的未来,一旦未来被“实现”(在 Future.then() 内),然后我保存数据并调用 SetState();用新数据重建列表。
问题是一旦 setState() 被调用,Build 方法就会重新运行,这会再次为我提供用户,这会导致从第二个 API 检索用户和数据的无限循环。
这似乎是一个典型的场景,但我不知道如何使用 StreamBuilder 解决这个问题。我以前的解决方案是在 initState 中检索用户,因此不会无休止地召回。
有什么建议吗?
“getOtherAPIData”循环检索到的用户并将数据“distance”添加到列表中,列表根据与most/least距离的用户排序。
代码:
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<List<IsFriend>>(
stream: viewModel.isFriendStream(),
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
List<IsFriend> friends = snapshot.data;
if (friends == null || friends.isEmpty) {
return Scaffold(
body: Center(
child: Text("Friend list is empty :("),
)
);
} else {
userList = friends;
getOtherAPIData();
return getListview(userList);
}
}
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
)
);
}
),
..
..
void getOtherAPIData() async {
for (IsFriend friend in userList) {
await fitbitServ.getData(friend.user.uid).then((fitData) {
setState(() {
setDistanceOnUser(fitData.distanceKm, friend.user.uid);
totalDistance += fitData.distanceKm;
sortUsers(userDataList);
userData[friend.user.uid] = fitData;
});
});
}
}
永远不要调用从 build
方法中开始加载数据的方法。我使用的正常流程是:
- 开始在小部件的构造函数中加载数据。
- 数据可用时调用
setState
。
- 从
build
中的状态渲染数据。
我在构建方法中使用 StreamBuilder 从 firestore 检索用户信息,并在它显示 Listview.builder 后立即检索。
检索到用户信息后,我使用用户 ID 调用另一个 API 来检索我想在列表中显示的其他一些信息。这给了我每个用户的未来,一旦未来被“实现”(在 Future.then() 内),然后我保存数据并调用 SetState();用新数据重建列表。
问题是一旦 setState() 被调用,Build 方法就会重新运行,这会再次为我提供用户,这会导致从第二个 API 检索用户和数据的无限循环。
这似乎是一个典型的场景,但我不知道如何使用 StreamBuilder 解决这个问题。我以前的解决方案是在 initState 中检索用户,因此不会无休止地召回。 有什么建议吗?
“getOtherAPIData”循环检索到的用户并将数据“distance”添加到列表中,列表根据与most/least距离的用户排序。 代码:
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<List<IsFriend>>(
stream: viewModel.isFriendStream(),
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
List<IsFriend> friends = snapshot.data;
if (friends == null || friends.isEmpty) {
return Scaffold(
body: Center(
child: Text("Friend list is empty :("),
)
);
} else {
userList = friends;
getOtherAPIData();
return getListview(userList);
}
}
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
)
);
}
),
..
..
void getOtherAPIData() async {
for (IsFriend friend in userList) {
await fitbitServ.getData(friend.user.uid).then((fitData) {
setState(() {
setDistanceOnUser(fitData.distanceKm, friend.user.uid);
totalDistance += fitData.distanceKm;
sortUsers(userDataList);
userData[friend.user.uid] = fitData;
});
});
}
}
永远不要调用从 build
方法中开始加载数据的方法。我使用的正常流程是:
- 开始在小部件的构造函数中加载数据。
- 数据可用时调用
setState
。 - 从
build
中的状态渲染数据。