Home > Blockchain >  .map is returning only the last element of array React
.map is returning only the last element of array React

Time:10-16

I'm creating a blog type app with cloud firestore just as a project to learn some stuff. However I'm having an issue where only the last element of my state array, 'blogs', is being returned inside of the .map method.

Any help with this is appreciated, thanks!

const [blogs, setBlog] = useState([]);
const fetchBlogs = async () => {
    const response = await getDocs(collection(db, "blog posts"));
    let postArray = [];
    response.docs.forEach((blogpost) => {
        postArray.push(blogpost.data());
    });
    console.log(postArray)
    postArray.forEach(post => {
        setBlog([...blogs, post]);
    });
}
useEffect(() => {
    fetchBlogs();
}, []);

return (
    <ul className="posts-container">
       { blogs.map((blog) => { 
           console.log(blog); //this outputs each of the individual posts, but only the last is displayed as an <li>
           return ( <li key={blog.title}>{blog.title}</li> )
        })}
    </ul>
)

CodePudding user response:

Instead of this:

postArray.forEach(post => {
  setBlog([...blogs, post]);
});

Try doing this:

setBlog(postArray);

I am not sure as to what exactly happens, but this seems like the most suspicious piece in your code.

CodePudding user response:

You are overriding the blog post twice, try it this way

const fetchBlogs = async () => {
    const response = await getDocs(collection(db, "blog posts"));
    setBlog([...blogs, ...response.docs.map(blogpost => blogpost.data())])
}

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

CodePudding user response:

You probably want to put the response in your state without doing the forEach()

setBlog(postArray);

Or even (depending on data structure)

const [blogs, setBlog] = useState([]);

const fetchBlogs = async () => {
    const response = await getDocs(collection(db, "blog posts"));
    setBlog(response.data); // set to whatever you need
}

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

return (
    <ul className="posts-container">
       { blogs.map((blog) => { 
            return <li>( <li key={blog.title}>{blog.title}</li> )
          }
       )}
    </ul>
);
  • Related