【问题标题】:State not updating until external event状态直到外部事件才更新
【发布时间】:2021-09-26 05:59:43
【问题描述】:

我正在使用 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** 

费用状态仅在我更改应用程序中的其他状态后才会更新。我试图通过改变使用效果函数中的一些其他状态来解决这个问题,没有骰子。此外,我尝试将状态作为依赖项传递给使用效果。没什么……

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

【问题讨论】:

    标签: reactjs firebase google-cloud-firestore react-hooks


    【解决方案1】:

    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();
      }, []);
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2021-09-26
        • 2021-10-06
        • 2021-06-09
        • 2019-08-28
        • 1970-01-01
        • 2011-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多