I'm trying to get data from Axios but while the data is being fetch the return statement gets executed, I think.
import axios from 'axios'
import React, { useState, useEffect} from 'react'
export default function Overall() {
const [post, setPost] = useState({
date:null,
total:null
});
useEffect(() => {
async function fetchData(){
await axios.get(`https://data.covid19india.org/v4/min/data.min.json`).then((response) => {
console.log("Inside Then block");
setPost({'total':Object.entries(response.data).map(([k,v])=>
// console.log(k,v.meta.last_updated,v.total.confirmed)
v.total.confirmed
).reduce((prev, curr)=>prev curr,0)
})
setPost({'date':Object.entries(response.data)[0][1].meta.last_updated})
});
}
fetchData()
console.log("Data Fetched");
}, []);
console.log("Post: ",post);
return (
<div className='overall-container'>
<div>
<h2>India</h2>
</div>
<div>
<h2>Total: {post.total}</h2>
<h2>Date: {post.date}</h2>
</div>
</div>
)
}
The problem is that in return only {post.date}
is working while {post.curr}
is not. I don't know why? I'm new to react so I don't know much. I would appreciate if someone could explain this.
CodePudding user response:
I'm assuming that you meant {post.total}
instead of {post.curr}
You could change from:
setPost({'total':Object.entries(response.data).map(([k,v])=>
// console.log(k,v.meta.last_updated,v.total.confirmed)
v.total.confirmed
).reduce((prev, curr)=>prev curr,0)
})
setPost({'date':Object.entries(response.data)[0][1].meta.last_updated})
To:
setPost({
total: Object.entries(response.data).map(([k,v])=>
// console.log(k,v.meta.last_updated,v.total.confirmed)
v.total.confirmed
).reduce((prev, curr)=>prev curr,0),
date: Object.entries(response.data)[0][1].meta.last_updated
});
And it should work. However, maybe it'd be better to seperate date and total into two different states?
CodePudding user response:
This is a bad practice to do async stuff in useEffect. You should create a separate function and call it from useEffect.
Your error is caused because you call setPost to update total and then once again to update date.
When you call setPost it will erase previous value for post. If you need to keep previous value you can do:
setPost((prev) => ({
...prev,
date: new Date()
}));
In your code you should call setPost only once
import React, { useState, useEffect} from 'react'
import axios from 'axios'
export default function Overall() {
const [post, setPost] = useState({});
const fetchData = async () => {
try {
const response = await axios.get(`https://data.covid19india.org/v4/min/data.min.json`)
// tranform your response and then set it to state at once
const total = 1 // replace with your total
const date = new Date() // replace with your date
setPost({ total, date })
} catch(err) {
console.log(err);
}
}
useEffect(() => {
fetchData()
}, []);
console.log("Post: ",post);
return (
<div className='overall-container'>
<div>
<h2>India</h2>
</div>
<div>
<h2>Total: {post?.total}</h2>
<h2>Date: {post?.date}</h2>
</div>
</div>
)
}