状态直到外部事件才更新

IT技术 reactjs firebase google-cloud-firestore react-hooks
2021-05-10 08:51:49

我正在使用 useEffect 运行一个从 firebase 获取数据的函数。

数据被抓取得很好,但是 setState 函数似乎直到另一个状态改变后才会生效......我认为使用 useEffect 会在第一次渲染之前运行。

function App() {
  const [expenses, setExpenses] = useState([]);
  const roster = [];
  React.useEffect(() => {
    const getRoster = async () => {
      var db = firebase.firestore();

      db.collection("Roster")
        .get()
        .then((querySnapshot) => {
          querySnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots
            var data = doc.data();
            data.ID = doc.id;
            roster.push(data);
          });
        });
      console.log("setting roster");
      setExpenses(roster);
      console.log("roster", roster);
      console.log("expenses", expenses);
    };
    getRoster();
  }, []);

控制台返回以下内容

setting roster
roster [all data from firebase here]
expenses [blank], **expenses is the state variable** 

费用状态仅在我更改应用程序中的其他状态后更新。我试图通过更改使用效果功能中的其他一些状态来解决这个问题,没有骰子。我也尝试将状态作为使用效果的依赖项传递。没有什么...

我一定做错了什么,但我不确定那是什么。我的目标是在第一页加载时更新费用状态。

2个回答

setExpenses(roster);应该在 .then 内部调用,因为它 .get 是一个异步调用并且需要一些时间,所以在这段时间内你的 setExpenses(roster); 被调用,它的初始值是 roster。所以你应该使用你的 setExpenses(roster); 如下

 React.useEffect(() => {
    const getRoster = async () => {
      var db = firebase.firestore();

      db.collection("Roster")
        .get()
        .then((querySnapshot) => {
          querySnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots
            var data = doc.data();
            data.ID = doc.id;
            roster.push(data);
          });


          console.log("setting roster");
          setExpenses(roster);
          console.log("roster", roster);
          console.log("expenses", expenses);
        });
    };
    getRoster();
  }, []);

setExpenses 调用应该直接放在 querySnapshot.forEach 调用之后,但仍然在 .then((querySnapshot) => { ... } 处理程序中。因为它当前放置在该处理程序之后,所以在第一次渲染时立即执行,而不是获取 Firebase 数据时。