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 заключается в том, что вы не можете гарантировать, что last"setPosts" действительно завершится до следующего l oop Таким образом, ваше состояние (в данном случае "posts") может быть устаревшим.
Итак, net всего этого, мой шаблон будет:
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>