adjash
adjash

Reputation: 173

.map is returning only the last element of array React

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>
)

Upvotes: 1

Views: 2291

Answers (3)

axtck
axtck

Reputation: 3965

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>
);

Upvotes: 1

Abraham
Abraham

Reputation: 9865

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(), []);

Upvotes: 1

Maksym Shcherban
Maksym Shcherban

Reputation: 783

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.

Upvotes: 1

Related Questions