Faced with a problem, when you switch to a page of posts all posts are hidden and only on pressing the button
`<li onClick={()=> setFiltered(posts)}><a>All</a><span></span></li>`
displays all the posts, although all posts should be displayed immediately when you go to the page. But the filter works fine, please can you point out where I made a mistake, if anything I output the posts from firebase
Functions
const [posts, setPosts] = useState([]);
const [filtered, setFiltered] = useState([]);
const postsCollectionRef = collection(db , "posts");
const menuItems = [...new Set(posts.map((Val) => Val.category))];
useEffect(() => {
const getPosts = async () => {
const data = await getDocs(postsCollectionRef);
setPosts(data.docs.map((doc) => ({...doc.data(), id: doc.id})));
setFiltered(posts);
}
getPosts();
}, [])
// filter function
const filterItem = (category) => {
const newItem = posts.filter(newVal => newVal.category === category);
setFiltered(newItem);
};
Buttons Category
<li onClick={()=> setFiltered(posts)}><a>All</a><span></span></li>
{
menuItems.map((Val, id)=>{
return <li key={id} onClick={()=> filterItem(Val)}><a>{Val}</a><span></span></li>
})}
Output posts
<div className="gallery-row">
{
filtered.map((posts, i) => {
return( <Link key={i} to={'/product/' posts.id}>Post</Link>)
})}
</div>
CodePudding user response:
When setFiltered
is called inside of useEffect, the value of posts
is still []
, the initial value. The issue you're experiencing is called stale closures.
In many cases, this can be fixed by adding the stale value to the useEffect's dependency array, but in your case that would create an infinite loop.
Based on your code, the simplest solution is the following:
useEffect(() => {
const getPosts = async () => {
const data = await getDocs(postsCollectionRef);
const posts = data.docs.map((doc) => ({...doc.data(), id: doc.id}));
setPosts(posts);
setFiltered(posts);
}
getPosts();
}, [])