Home > front end >  Fetching and rendering a component in a loop
Fetching and rendering a component in a loop

Time:01-06

I have a string array that contains usernames. I want to fetch those users in a loop, put them in an array and render a component for each user. I can retrieve the data from API and print it on console but the code below gives me a white screen.

Here I'm trying to fetch data one by one using fav_list array than contains usernames. Then I want to send the data to another component called InfluencerFavoritesCard and render them. Where I'm doing wrong?

import React from 'react'
import InfluencerFavoritesCard from '../components/influencerFavoritesCard/InfluencerFavoritesCard';

import "./indexPages.css"
import "./favorites.css"

const fav_list = ["cagritaner", "acunilicali", "neslihanatagul"]; 

async function ListFavorites() {

  let array = new Array;
  var fetches = [];

  for (let i = 0; i < fav_list.length; i  ) {
    console.log(fav_list[i]);

    let uname = fav_list[i];

    fetches.push(
      fetch(`http://localhost:3001/api/users/${uname}`)
      .then(res => {return res.text(); })
        .then(res => {
            array.push(res);
            console.log(res);
          }
      )
    );
  }

  
  Promise.all(fetches).then(function () {
    console.log(fetches);
    console.log(array[0]);
    console.log(array.length);
  });

  return (
    <div>
      {array.map(item => (< InfluencerFavoritesCard  infCard = { item } /> ))}
    </div>
  );

}


function Favorites() {
  return (
    
    <div className='favoritesMain'>

      <div className='favoritesTitle-div'>
        <h3 className="favoritesTitle">FAVORİLER</h3>
      </div>

      <div className='favoritesContainer-wrapper'>
        <div className='favoritesContainer'>

          {<ListFavorites/>}

        </div>  
      </div>

      <div className='favoritesFooter'></div>
      
    </div> 

  );
}

export default Favorites

InfluencerFavoritesCard.jsx

import React from 'react';
import './influencerFavoritesCard.css';
    
const InfluencerFavoritesCard = ({ infCard }) => {
  return (
    <div className='infCard'>


      <div className='infCard-text-info' >
        <div className='infCard-name'>
          <h3>{infCard.name}</h3>
        </div>
        <div className='infCard-username'>
          <h4>{infCard.username}</h4>
        </div>
        <div className='infCard-categories'>
          <h4>{infCard.categories}</h4>
        </div>
      </div>


    </div>
  )
}

export default InfluencerFavoritesCard;

CodePudding user response:

To fetch data asynchronously, you need to use the useEffect hook. You should store the data using a useState hook and then set that data when you get a response from your fetch request.

CodePudding user response:

The thing is that return statement is being rendered before all the promises are resolved, meaning that it's empty. This is exactly how it should work, so no bug here.

What you need to do is as other mentioned, use useState and useEffect to control the data:

// This will hold your collection 
const [users, setUsers] = useState([])
...
// And here you need to update that collection
useEffect(()=>{
const temp = []
fetch(`http://localhost:3001/api/users/${uname}`)
  .then(res => {return res.text(); })
    .then(res => {
     temp.push(res);
    }
)
setUsers(temp)
}, []) 

Later on the return you can do this:

// This controls if there are no users
if(users.length <= 0){
 return <>There are no users</>
}

return (
<div className='favoritesMain'>
 <div className='favoritesTitle-div'>
  <h3 className="favoritesTitle">FAVORİLER</h3>
 </div>

 <div className='favoritesContainer-wrapper'>
  <div className='favoritesContainer'>
   {users.map(item => (<InfluencerFavoritesCard  infCard = { item } /> ))}
    </div>
 </div>

 <div className='favoritesFooter'></div>
</div> 
);
  • Related