I am confused on how an async function works.
The console.log returns an error because the data.rates does not exist yet. But I thought because the useEffect function is async anything under it would be called after the async is over.
function App() {
const [data, setData] = useState();
useEffect(() => {
(async () => {
const result = await axios.get(
"https://open.exchangerate-api.com/v6/latest"
);
setData(result.data);
})();
}, []);
console.log(data.rates); <-- Error data.rates does not exist
return <div>{!data ? "Loading..." : "Hello"}</div>;
}
I feel like none of the answers actually answer the question.
useEffect
doesn't stop the flow of execution, it doesn't matter what you're doing inside the callback passed to it. So the console.log(data.rates)
gets executed and then once the component is mounted the callback passed to useEffect
is executed. Since the state is being changed in the callback( setData(result.data)
) this triggers a re-render and this time you should see that the correct value is logged without any errors.
Your assumption is actually correct, useEffect in this scenario will run when the Component is mounted that means console.log
will be called twice--first with initial value (which is undefined), second is after useEffect performed the side-effect when data is actually set (setData) after the request is fulfilled. You would typically provide a "loading" state while data is stale.
function App() {
const [loading, setLoading] = useState(false);
const [data, setData] = useState();
useEffect(() => {
(async () => {
setLoading(true);
const result = await axios.get(
"https://open.exchangerate-api.com/v6/latest"
);
setLoading(false);
setData(result.data);
})();
}, []);
if (loading) return <div>Fetching data...</div>
return <div>Hello</div>;
}
Try doing this (I've kind of created a workaround)
function App() {
const [data, setData] = useState();
useEffect(()=>{
const setObtainedData=async()=>{
const result = await axios.get("https://open.exchangerate-api.com/v6/latest");
setData(result.data);
};
setObtainedData();
},[]);
if(data){
console.log(data.rates);
}
return <div>{!data ? "Loading..." : "Hello"}</div>;
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.