I have a react app like so:
import React, { useState } from 'react';
import axios from 'axios';
const Body = () => {
const defaultVersions = [
{
version: '2.96.0',
status: null,
}
];
const [versions, setVersions] = useState(defaultVersions);
const getData = version => {
axios.get(`https://cdn10/${version}/en-US/test.js`)
.then(response => {
console.log(response.status);
return response.status;
})
.catch(err => {
console.log('in here');
})
};
const onClick = () => {
setVersions(versions.map(item => {
const { version } = item;
return { version, status: getData(version) };
}));
};
return (
<>
<button onClick={onClick}>Check Versions</button>
<ul>
{versions.map(item => {
const { version, status } = item;
return <li>{`${version}: ${status}`}</li>
})}
</ul>
</>
);
}
export default Body;
And the console.log
in getData
works, but when I try to use getData
to set the new value in my state on the button click, it’s returning undefined
. I’ve tried making getData
async/await, but that didn’t work. Any insight is appreciated!
3
Answers
You can use
async/await
syntax andPromise.all()
method.For example:
To see the whole example, please see codesandbox.io.
Problem is that your getData is not returning anything, yes you are calling your function but you aren’t returning the promise returned by your axios call. That’s the first problem.
Second problem is that you are expecting multiple results when you click the button since you are doing a map of versions, in other words it’s not just one promise, there could be many so you need to await all of them before setting the values
I think it’s cleaner if we write it this way
This function can be improved but for sakes of this example this will work
First of all, you missed
return
ingetData
. In JavaScript the result of function that has noreturn
isundefined
. So it always returnsundefiend
.When we return
axios.get
the return type isPromise
. So we should useasync
await
or.then
. You can update your code like this.PS: When rendering list elements, we need to define a
key
prop.