Home > Enterprise >  React async data in useEffect doesnt trigger render
React async data in useEffect doesnt trigger render

Time:05-23

I have the following state const [articles, setArticles] = useState([]);

and I'm trying to fetch some initial data using useEffect ->

useEffect(() => {
   const init = async () => {
     const newList = await getArticlesIntoDOM();
     setArticles(newList);
   };

   init();
 }, []);

To check if the data is correct, I'm rendering it using simple HTML <h1>{JSON.stringify(articles)}</h1>

My problem is:

  • if getArticlesIntoDOM contains only 1 API call, it works fine
  • if i have multiple API calls inside this method, I'm not getting the data rendered.

Example of code that fails:

const getArticlesIntoDOM = async () => {
    const articles = [];

    posts.forEach(async (post) => {
      const user = await getUserById(post.userId);
      const comments = await getCommentsByPostId(post.id);
      const imageUrl =
        "https://picsum.photos/1280/720?random="   getRandom(300);

      articles.push({
        postId: post.id,
        title: post.title,
        author: user.name,
        imageUrl: imageUrl,
        comments: comments,
      });
    });

    return articles;
  };

the state is changed but the render is not triggered. I made another button that console.log the current state and the data is correct but it is never outputted in the <h1>

!!!! I found a solution -> If i use a simple for loop instead of foreach everything is working as expected

CodePudding user response:

The UseEffect is triggered when the value in the brackets changing , when you put bracket empty the Useeffect trigger when the component rendered.

I suggest you to try to put another useEffect like that :

useEffect(() => {
  console.log(articles)
}, [articles])

CodePudding user response:

From your code, articles is an object and you are trying to render it in h1, wont render. You have to use, map function to render it

....
articles.map((post) => {
 
  return (
    <h1> {post.author} </h1>

)
}

    ....

Now you can render each data inside like that

  • Related