Home > Enterprise >  How to tell useEffect to wait for data API?
How to tell useEffect to wait for data API?

Time:11-24

I want to get data from an API and map the response to display it.

import React from 'react'
import { useState, useEffect } from 'react'
import axios from 'axios'

export default function Nav() {

   const options = {
      method: 'GET',
      url: 'url',
      headers: {
         'x-rapidapi-host': 'host',
         'x-rapidapi-key': 'key'
      }
   }

   const [allCoins, setAllCoins] = useState([])

   useEffect(() => {
      axios.request(options)
      .then(res => setAllCoins(res.data.data.coins))
      .catch(err => console.error(err))
   }, [])

   return (
      <nav>
          {allCoins.map(el => {
              <img src={el.iconUrl} alt="" />
              <h2>{el.name}</h2>
              <span>{el.symbol}</span>
          })}
      </nav>
   )
}

But nothing is displayed. I know it's an asynchronous problem, I have to wait the data in the state before mapping it, but I have no idea how to do it and I didn't find a solution on Google.

CodePudding user response:

Okay finally I solved my problem, it wasn't asynchronous but just syntax mistake. I used {} instead () for the map arrow function.

allCoins.map(el => { ...})❌

allCoins.map(el => ( ...))✅

CodePudding user response:

You need to call the api asynchronously, which you're not doing in here. If everything else is correct, this two code block should work.

useEffect(() => {
    const getData = async () => {
        axios.request(options)
            .then(res => setAllCoins(res.data.data.coins))
            .catch(err => console.error(err))
    }
    getData()
}, [])

We directly implement the async in useEffect, we can only achieve this by creating a asynchronous method and call it inside useEffect hook.

And also you need to modify your code in map:

{
    allCoins.length > 0 && allCoins.map(el => {
        return <>
            <img src={el.iconUrl} alt="" />
            <h2>{el.name}</h2>
            <span>{el.symbol}</span>
        </>
    })
}

JSX expressions must have one parent element

So you need to wrap your element by one single element or React.Fragment.

  • Related