How to dynamically render react components?

I have a website where if I press a button it fetches a post object from a database and adds it into an array. I need to somehow display all the objects in the array as react components and also to update the list every time when a new post is added.

I’ve been trying to use the map() method but I can’t get it to display the new posts that are added when I click the button.

Main component:

import Post from './Post'
import { useState, useEffect, createElement } from 'react'
import { useCookies } from 'react-cookie';
import Axios from 'axios'


const Content = () => {

    const [postArr, setPostArr] = useState([])

    const getPosts = ()=>{
        Axios.defaults.withCredentials = true
        Axios({
            method: 'get',
            url: 'http://localhost:3010/api/getpost/',
            headers: {'Content-Type': 'multipart/formdata' }
        })
        .then((response) => {
            addPostToPostArray(response)
        })
        .catch((response) => {
            console.log(response);
        });
    }
    const addPostToPostArray = (response) => {
        let imgName = response.data.imgurl.slice(68, 999999)
        let sendObj = {
            id:response.data.id,
            posterid:response.data.posterid,
            imgurl:`http://localhost:3010/images/${imgName}`,
            title:response.data.title,
            likes:response.data.likes,
            date:response.data.date
        }
        postArr.push(sendObj)

        /*
        A fetched post will look like this:
        {
        id:123, posterid:321, imgurl:`http://localhost:3010/images/333.png`,
        title:'best title', likes:444, date:111111
        }
        */
    }

    return ( 
        <div>
            {postArr.map((e) => {
                return <Post post={e}/>
            })}
            <button onClick={getPosts}>load post</button>   
        </div>
    );
}
 
export default Content;

Post component:

const Post = (props) => {

    const post = props.post

    return ( 
            <div className='post-frame'>
                <h1>{post.title}</h1>
                <div className="image-frame">
                    <img src={post.imgurl}></img>
                </div>
                <p>{post.likes}</p>
                <p>{post.posterid}</p>
            </div>                                 
    );
}
 
export default Post;

>Solution :

To update the state of the component you need to call that setPostArr function with the updated array. Without that the state of the component never get’s updated.

Here’s an example

const Content = () => {

    const [postArr, setPostArr] = useState([])

    const getPosts = () => {
        ...
    }

    const addPostToPostArray = (response) => {
        let sendObj = {
            ...
        }

        // ~ This part here
        setPostArr([...postArr, sendObj])
        
       // ~ Instead of
       // postArr.push(sendObj)
    }

    return ...
}

Leave a Reply