为什么我在尝试从firebase读取数据时会得到一个空数组?

pnwntuvh  于 2023-08-07  发布在  其他
关注(0)|答案(2)|浏览(106)

我目前正在开发一个简单的todo crud应用程序。我只是似乎无法让我的数据显示在屏幕上。

const Home = () => {

  const [todos,setTodos] = useState([]);

  const getTodos = async () =>{
    const querySnapshot = await getDocs(collection(db, "todos"));
    
    querySnapshot.forEach((doc) => {        
      setTodos([...todos,doc.data()])
      console.log(doc.data())
      console.log(todos)
    });  
  }

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

  return (    
    <div>Home</div>
  )
}

字符串
现在console.log(doc.data())显示了每个数据集,但是todos数组要么只获得分配的第一个值,要么返回一个空数组。
有什么想法吗?

wb1gzix0

wb1gzix01#

状态设置器操作是 * 异步的 *,调用setTodos不会改变todos变量指向的数组中的内容。相反,它会安排一个对组件函数的新调用,您将在其中从useState获取新数据。这就是为什么console.log(todos)和对setTodos的重复调用都不起作用的原因:两者都使用来自todos的 * 过时 * 信息。
当基于现有状态(当前数组)设置状态时,通常最好使用状态设置器的回调形式。所以最小的变化是:

// But keep reading!
querySnapshot.forEach((doc) => {        
    setTodos((todos) => [...todos, doc.data()]);
});

字符串
这样做是可行的,但是您可能需要执行循环,然后在完成后调用setter一次,而不是在循环中调用setTodos
我不使用Firebase,但是Nick Parsons发现并发布了这个链接,说你可以通过docs属性以数组的形式获取文档。所以你可以在这个数组上调用map

setTodos((todos) => [...todos, ...querySnapshot.docs.map((doc) => doc.data())]);

k97glaaz

k97glaaz2#

而不是使用setTodos([...todos,doc.data()])
试试这个

querySnapshot.forEach((doc) => {        
      setTodos((prev) => [...prev, doc.data()])
      console.log(doc.data())
      console.log(todos)
    });

字符串

相关问题