为什么国家总是空着?

时间:2020-04-15 11:47:05

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

我已经彻底解决了所有提出的问题,但没有一个直接适用于我的问题。我正在遍历用户ID数组并对其进行匹配,以从我的Firestore数据库中获取用户。我得到的结果没有问题,但是当我将其存储在状态数组中并运行控制台日志时,我的状态数组始终为空。第一个console.log起作用并显示数据库的结果。

这是我的代码:

const UsersScreen = (props) => {

    const [state, setState] = useState({
        users: []
    });  

    const getUserProfiles = () => {
        let users = [];
        //networkUsers is an array with the ids
        networkUsers.forEach(userId => { 
            db.doc(userId).get().then((doc) => {
                users.push(doc.data());
                console.log('localusers', users)
            }).catch((error) => {
                console.log('caught error', error)
            })
        });

        setState({ users: users });
    };


    useEffect(() => {
        getUserProfiles();
    }, []);

console.log('state', state.users)
}

请帮助。

1 个答案:

答案 0 :(得分:4)

从Firestore提取文档的逻辑是异步的。不过,对setState的调用是同步的。始终会在文档获取之前之前。解决方案是先获取文档,然后然后设置状态。这是一个示例:

const UsersScreen = (props) => {
  const [state, setState] = useState({
    users: [],
  });

  const getUserProfiles = () => {
    Promise.all(networkUsers.map((userID) => db.doc(userId).get()))
      .then((docs) => {
        setState({ users: docs.map((doc) => doc.data()) });
      })
      .catch((err) => {
        console.log("caught error", error);
      });
  };

  useEffect(() => {
    getUserProfiles();
  }, []);

  console.log("state", state.users);
};

一旦从Firestore中提取了每个用户,Promise.all调用便会解析(尽管您可以一次提取它们)。一旦有了用户,就可以使用map在用户上循环,以提取文档数据并设置状态。这是async/await的替代方案:

const UsersScreen = (props) => {
  const [state, setState] = useState({
    users: [],
  });

  const getUserProfiles = async () => {
    try {
      const docs = await Promise.all(
        networkUsers.map((userID) => db.doc(userId).get())
      );

      setState({ users: docs.map((doc) => doc.data()) });
    } catch (err) {
      console.log("caught error", error);
    }
  };

  useEffect(() => {
    getUserProfiles();
  }, []);

  console.log("state", state.users);
};