Flutter使用StreamBuilder与setState更新

时间:2020-09-01 12:19:27

标签: firebase flutter google-cloud-firestore stream-builder

我正在使用build方法中的StreamBuilder从Firestore中检索用户信息,并在将其与Listview.builder一起显示之后。

一旦我检索了用户信息,我将使用用户ID调用另一个API来检索我想显示在列表中的一些其他信息。这给我每个用户一个Future,一旦Future被“实现”(在Future.then()内部),然后我保存数据并调用SetState();。用新数据重建列表。

问题是一旦调用setState()重新运行Build方法,这再次为我提供了用户,这导致了从第二个API检索用户和数据的无休止循环。

这似乎是一个典型的场景,但是我不知道如何使用StreamBuilder解决此问题。我以前的解决方案在initState中检索了用户,因此不会无休止地对其进行调用。 有提示吗?

“ getOtherAPIData”循环检索到的用户,并将数据“距离”添加到列表中,并且列表基于距离最大/最小的用户进行排序。 代码:

@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;
    });
  });
}

}

1 个答案:

答案 0 :(得分:0)

永远不要调用从build方法内部开始加载数据的方法。我使用的正常流程是:

  1. 开始将数据加载到小部件的构造函数中。
  2. 在数据可用时致电setState
  3. build中的状态呈现数据。