Reputation: 31
I made a promise function to get a JSON file from the official NBA API. In this function I'm trying to update a usestate
, but I keep getting an empty array after setting the state. What am I overlooking?
const Games = () => {
const [gameData, setGameData] = useState([]);
const { readableDate } = useContext(NBAContext);
const insertTime = readableDate.split('/');
useEffect(() => {
const jsonSrc = `https://cors-anywhere.herokuapp.com/http://data.nba.net/10s/prod/v1/${insertTime[2]}${insertTime[1]}${insertTime[0]}/scoreboard.json`;
const getScores = async () => {
const response = await fetch(jsonSrc);
return await response.json()
};
getScores().then((result) => {
console.log(result)
setGameData(result);
console.log(gameData);
});
}, [readableDate])
Upvotes: 1
Views: 83
Reputation: 6403
edit: actual answer - setting state, whether with this.setState
or the useState
hook, is an asynchronous process. This means that calling console.log(gameData)
right after setGameData(results)
will result in the previous result (in this case, empty array). If you want to access gameData
variable with results of the API call, use another useEffect
hook with gameData
as a dependency:
useEffect(() => {
console.log(gameData)
}, [gameData])
initial answer, code improvement/advice: remove the line where you wrap the code inside getScores
in a promise, and just return the result of await response.json()
.
useEffect(() => {
const jsonSrc = `https://cors-anywhere.herokuapp.com/http://data.nba.net/10s/prod/v1/${insertTime[2]}${insertTime[1]}${insertTime[0]}/scoreboard.json`;
const getScores = async () => {
try {
const response = await fetch(jsonSrc);
return await response.json()
} catch (err) {
console.log(err)
throw err
}
}
getScores().then((result) => {
console.log(result)
setGameData(result.games);
});
}, [readableDate])
Upvotes: 0
Reputation: 8774
Just like setState, the setting of useState is also asynchronous. That's why the console.log(gameData) prints the empty array. Since its still the previous array.
After the setting of the data, a new render will be called with the updated data and you can display it.
Upvotes: 0