Why is State always empty?

蓝咒 提交于 2020-04-18 05:48:36

问题


I have thoroughly gone through all the asked question and none of them apply to my problem directly. I am looping through an array of user ids and matching them to get a user from my firestore db. I get the result back with no problem but when i store it in the state array and run a console log, my state array is always empty. The first console.log works and shows the results from the db.

Here's my code:

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

Please help.


回答1:


The logic that fetches the document from Firestore is asynchronous. The call to setState is synchronous though. It will always before the document has been fetched. The solution would be to fetch the documents then set the state. Here is an example:

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

The Promise.all call resolves once every user has been fetched from the Firestore (maybe you could fetch them at once though). Once we have the users we loop over them with map to extract the data of the document and set the state. Here is an alternative with 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);
};


来源:https://stackoverflow.com/questions/61227909/why-is-state-always-empty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!