reactjs - 无法使用反应挂钩呈现从 Firebase 成功获取的数据集合
问题描述
我正在从 firebase 获取一个文档集合,然后将其传递给一个状态,以便在更新时重新渲染它。
const [posts, setPosts] = useState([])
const fetchPosts = () => {
firebase.firestore().collection('posts').get()
.then(snap => {
snap.docs.forEach(doc => {
setPosts([...posts, doc.data()])
console.log(doc.data())
})
})
}
useEffect(() => {
fetchPosts()
}, [])
我还将这个状态传递给其他组件,因此它们也使用更新的状态重新渲染
但是反应只是渲染第一个集合文档并在控制台中给出错误:'每个孩子都应该有一个唯一的关键道具'。我的每个 doc 对象内部都有一个唯一的 id,我将其作为每个帖子的键传递
<div className="posts section">
{posts.map(post=>{
return <Link to={'/posts/'+post.id}><PostCard post={post} key={post.id} /></Link>
})}
</div>
解决方案
Google 不建议使用文档/数组数据作为键,因为后续渲染可能效率低下。一个可爱的 React 函数可以解决独特的关键问题。
<div className="posts section">
{React.Children.toArray(
posts.map(post => {
return (
<Link to={"/posts/" + post.id}>
<PostCard post={post} />
</Link>
);
})
)}
</div>
您可能遇到的另一个问题是 useEffect 必须是同步的。您可能希望将 fetchPosts 显式声明为异步。我使用以下内容来处理 querySnapshot:
return query
.get() //get the resulting filtered query results
.then(querySnapshot => {
return Promise.resolve(
querySnapshot.docs.map(doc => {
return {
...doc.data(),
Id: doc.id,
ref: doc.ref
};
})
);
})
.map 的最佳原因是您不能保证最后一个“setPosts”在您的下一个循环之前实际上已经完成,因此您的状态(在这种情况下是“posts”)可能是陈旧的。
所以,除此之外,我的模式是:
const [posts, setPosts] = useState([])
const fetchPosts = () => {
return firebase.firestore().collection('posts').get()
.then(snap => {
snap.docs.map(doc => {
console.log(doc.data())
return {
...doc.data(),
id: doc.id,
ref: doc.ref
};
})
});
}
useEffect(() => {
(async () => {
const newPosts = await fetchPosts();
setPosts(newPosts);
})();
}, [])
//[etc, etc]
return
//[etc, etc]
<div className="posts section">
{React.Children.toArray(
posts.map(post=>{
return <Link to={'/posts/'+post.id}><PostCard post={post} key={post.id} /></Link>
})
}
</div>
推荐阅读
- node.js - git 只保存我想要的某些文件并保护其他一些文件不被推送
- python - 在装饰器中扩展 Python 中的类
- amazon-web-services - AWS:将 ASG 附加到 ALB TG 时为 503
- powerbi - PowerBI 表和矩阵总计/小计未正确求和
- ruby-on-rails - 如何在 Rails 5 应用程序的子目录中嵌入 PHP 驱动的博客?
- web-scraping - 使用 Google 表格从网页抓取中提取链接文本
- ios - 如何将 .gif 文件加载到开发中的 pod
- android - hashSet上的android空指针异常
- c# - 2D 相机跟随 - 游戏对象在跳跃时闪烁
- ios - UIPageViewController页面切换时避免iOS状态栏抖动