React JS 状态未更新

时间:2021-05-08 13:39:11

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

我正在为 firebase cloud firestore 获取集合中的所有文档。我正在使用 useEffect 钩子调用一个函数,该函数获取所有文档,然后使用一组新文档设置状态,但状态似乎没有更新。

这是获取和更新状态的代码:

const fetchBlogs = () => {
        db.collection('blogs').get().then(querySnapshot => {
          querySnapshot.forEach(doc => {
            setBlogs([...blogs,{
              title:doc.data().title,
              imgURL: doc.data().imgURL,
              desc: doc.data().desc
            }])
          });
        });
    }

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

这是呈现博客的代码:

{
  blogs && blogs.map(blog=>{
    return(
      <Article
         key={blog.title}
         title={blog.title}
         imgurl = {blog.imgURL}
         desc={blog.desc}
       />
    )
  })
}

目前的结果是这样的: enter image description here

2 个答案:

答案 0 :(得分:1)

更新 state 中的 forEach 并不能保证状态更新。先生成数据,然后更新状态 state。您可以阅读 these answer 以了解有关在循环内运行 setState 的更多信息

const fetchBlogs = () => { // You can also move this inside `useEffect` incase if it's not reused. 
  db.collection('blogs').get().then(querySnapshot => {
    const querySnapshots = [] 
    querySnapshot.forEach(doc => {
      const { title, imgURL, desc } = doc.data()
      querySnapshots.push({ title, imgURL, desc })
    });
    setBlogs([...blogs, ...querySnapshots])
  });
  
}

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

答案 1 :(得分:1)

改变

querySnapshot.forEach(doc => {
  setBlogs([...blogs,{
    title: doc.data().title,
    imgURL: doc.data().imgURL,
    desc: doc.data().desc
  }])
});

setBlogs(
  querySnapshot.docs.map(doc => ({
    title: doc.data().title,
    imgURL: doc.data().imgURL,
    desc: doc.data().desc
  }))
);

多次调用 setBlogs() 并从闭包中引用 blogs 将会失败。每次调用 blogs 时,旧闭包中对 setBlogs() 的引用不会更新,因此一系列状态更新只会呈现快照中迭代的最后一个文档,就像您当前编写它的方式一样。