Home > Enterprise >  Map list of components in useEffect is there but trying to show in the jsx is empty
Map list of components in useEffect is there but trying to show in the jsx is empty

Time:12-18

Coding Hobbyist here. I've been learning basic react and APIs (fetch, then blocks - basic stuff).

I've got a useEffect that looks at an array to make several API calls. Then all that data is set in the react state as far as I can tell as an array of objects.

I then need to map over those objects and create a list of the component passing the state(gecko) into it with key - data.

When I console log inside the useEffect it seems to me that everything is as expected and the list of is being saved in the coinList variable and then being called in the jsx below {coinList}.

But it does not show up and even more when I try to console log the props.data in the component it doesn't console log anything, so it seems like the {coinList} isn't working.

Can someone help me see what I've missed? Thanks.

This is not all the code in the repo but all the relevant code for brevity’s sake if you want you can look at the repo here.

Dashboard Repo

function App() {
  const [gecko, setGecko] = React.useState([
      {id:'bitcoin',image:{small:'https://assets.coingecko.com/coins/images/1/small/bitcoin.png?1547033579'},market_data:{ market_cap_change_24h_in_currency:{usd:'Not Available' }}},
      {id:'dogecoin',image:{small:'https://assets.coingecko.com/coins/images/5/small/dogecoin.png?1547792256'},market_data:{market_cap_change_24h_in_currency:{usd:'Not Available'}}},
      {id:'ethereum',image:{small:'https://assets.coingecko.com/coins/images/279/small/ethereum.png?1595348880'},market_data:{market_cap_change_24h_in_currency:{usd:'Not Available'}}},
      {id:'litecoin',image:{small:'https://assets.coingecko.com/coins/images/2/small/litecoin.png?1547033580'},market_data:{market_cap_change_24h_in_currency:{usd:'Not Available'}}}
    ])

  const coinGeckoUrl = `https://api.coingecko.com/api/v3/coins/`
  const coinArr = ['bitcoin','dogecoin','ethereum','litecoin']
  let coinList = [];

React.useEffect(()=>{
      Promise.all(coinArr.map(coin => fetch(`${coinGeckoUrl}${coin}`)))
        .then(results => {
          Promise.all(results.map((res)=>{
            return res.json()
          }))
          .then(data=>{
            console.log(`gecko data block`)
            // console.log(data)
           setPreviousState('gecko', data)
            coinList = gecko.map((item)=>{
              return <Coin key={nanoid()} data={item} />
            })
            console.log(coinList)
          })
          .catch(err=>console.log(err))
        })
  },[])
  
  function saveToLocalStorage(name, info){
    console.log(`calling save to localStorage`)
    localStorage.setItem(name, JSON.stringify(info))
  }

  function retrieveLocalStorage(name){
    console.log('retrieving local Storage')
    switch(name) {
      case 'unsplash':
        unsplashController = JSON.parse(localStorage.getItem(name))
        break;
      case 'gecko':
        geckoController = JSON.parse(localStorage.getItem(name))
        break;
      default:
        console.log('bad switch statement')
    }
    
  }

  function setPreviousState(state, fetchData){
    console.log(`calling setPrevState ${state}`)
    // console.log(`${fetchData}`)
    let hadData;
    if(fetchData === undefined && retrieveLocalStorage(state) !== undefined){
      let prevData = retrieveLocalStorage(state);
      switch(state) {
        case 'unsplash':
            hadData = true;
            setUnsplash(()=>{
              return {...prevData}
            })
          break;
        case 'gecko':
            hadData = true;
            setGecko(()=>{
              return {...prevData}
            })
          break;
        default:
          hadData = false;
          console.log('bad switch statement')
      }
    } else if(fetchData !== undefined){
      console.log(`we had fetchData`)
      switch(state) {
        case 'unsplash':
            hadData = true;
            saveToLocalStorage(state, fetchData)
            setUnsplash(()=>{
              return {...fetchData}
            })
          break;
        case 'gecko':
            hadData = true;
            setGecko(()=>{
              return [...fetchData]
            })
          break;
        default:
          hadData = false;
          console.log('bad switch statement')
      }
    } else {
      hadData = false;
    }
    return hadData;
  }

return (
    <div id="--app-app-container">
      <div id='--app-dashboard-container' className='container' style={styles.container} >
        <div id='--app-top-container'>
          <div className='--app-left-container'>
            <h1>Left Container</h1>
            {coinList}
          </div>
          <div className='--app-right-container'>
            <h1>Right Container</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
          </div>
        </div>        
      </div>
    </div>
  )
}

CodePudding user response:

Few pointers

use state to store/update data from api render arrays in markup

const [coinList, setCoinList] = useState([]);

React.useEffect(() => {
      // consider using async functions to make code more readable
      Promise.all(coinArr.map(coin => fetch(`${coinGeckoUrl}${coin}`)))
        .then(results => {
          Promise.all(results.map((res)=>{
            return res.json()
          }))
          .then(data=>{
            console.log(`gecko data block`)
            // console.log(data)
           setPreviousState('gecko', data)

           // setting state will cause a new render
           // save transformed objects in state 
           setCoinList( gecko.map((item) => ({ id: nanoid(), data={item} }))
           // coinList = gecko.map((item)=>{
           //   return <Coin key={nanoid()} data={item} />
           // })
           // console.log(coinList)
          })
          .catch(err=>console.log(err))
        })

  },[])

return (
    <div id="--app-app-container">
      <div id='--app-dashboard-container' className='container' style={styles.container} >
        <div id='--app-top-container'>
          <div className='--app-left-container'>
            <h1>Left Container</h1>
            {
              coinList?.map(item => {
                 return (<Coin key={item.id} data={item.data} />)
              })
            }
          </div>
          <div className='--app-right-container'>
            <h1>Right Container</h1>
            <p>Lorem .</p>
          </div>
        </div>        
      </div>
    </div>
  )

The new beta docs are a good starting point to learn a lot about React check out updating objects and working with arrays

Hope it helps

  • Related