Home > Back-end >  In React, how can I make a single api call, set the result to a state variable, and display it?
In React, how can I make a single api call, set the result to a state variable, and display it?

Time:02-13

I am programming a react application where I need to make a single async api call, save the result to a state variable and display the result. I am using an axios instance where the response of the api call is a nested object. For example:

{
    kanji:
        {character: "", stroke:""},
    quote: "string"
}

So far I have the following code where I am able to console.log the homeData object successfully. However I get the error: 'TypeError: homeData is undefined'.

const Home = () =>{

    const [homeData, setHomeData] = useState({}) 

    const getHomeData = async()=>{
        instance.get("/data")
        .then(res =>{
            setHomeData(res.data)
        })
        .catch(error =>{
            console.log(error)
        })
    }
    
    useEffect(()=>{
        getHomeData()
    }, [])

    console.log(homeData)
    
    return(
        <>
          <p>{homeData}<p>
        </>
    )
}

This seems like a promise issue but I am not sure how to fix it. Thank you for your help in advance.

CodePudding user response:

This is not a promise issue, it has to due with the order in which the lifecycle methods run. useEffect runs after the component renders. This means when the component first renders, the homeData is an empty object. homeData will be present in the second render. The following code first checks if homeData exists, then if it exists, it displays the kanji character. Note also, you cant just display a raw object into the dom so you will have to access the homeData by property for it to display

const Home = () =>{

    const [homeData, setHomeData] = useState({}) 

    const getHomeData = async()=>{
        instance.get("/data")
        .then(res =>{
            setHomeData(res.data)
        })
        .catch(error =>{
            console.log(error)
        })
    }
    
    useEffect(()=>{
        getHomeData()
    }, [])

    console.log(homeData)
    
    return(
        <>
          <p>{homeData && homeData.kanji.character}<p>
        </>
    )
}
  • Related