从Firestore文档参考列表中获取数据以声明状态React

时间:2020-08-23 17:04:50

标签: javascript reactjs react-native google-cloud-firestore react-redux

我有一份Firebase DocumentReferences列表,我需要获取数据并使用该数据设置状态。

这是我尝试过的:

useEffect(() => {
      let x = [];
      roomData.players.forEach(
        async (playerRef: FirebaseFirestoreTypes.DocumentReference) => {
          const playerSnap = await playerRef.get()
          x.push(playerSnap.data())
        }
      );
      setPlayers(x)

该列表有2个项目。 状态被设置为3次。一次通常有2个对象。第二次将它设置为一个空数组,并且将其设置为3个仅包含一个对象。

1 个答案:

答案 0 :(得分:1)

首先,您忽略了关键部分,它是useEffect的第二个参数,它确定何时调用setPlayers。

第二,异步代码可能未按预期运行,因为x传递给setPlayers时的内容未同步。您无法在forEach中使用async,因为无法等待所有结果。因此,在这种情况下,setPlayers(x)可能会在x.push(playerSnap.data())之前被调用。

所以最简单的更改是将useEffect第一个参数重写为

roomData.players.forEach(
  async (playerRef: FirebaseFirestoreTypes.DocumentReference) => {
    const playerSnap = await playerRef.get();
    setPlayers(prevPlayers => [...prevPlayers, playerSnap]);
  }
);

这将异步更新播放器。

如果您需要播放器进行同步更新,例如仅更新一次UI,或像Firestore中那样反映播放器的顺序,则必须替换forEach。一种这样的方法是使用简单的for循环顺序获取。另一种方法是构造一个承诺数组并将其提供给Promise.all