Reputation: 1043
I have a component which has two state variables:
const [data, setData] = useState(null);
const [isDataLoading, setIsDataLoading] = useState(true);
const fetchData = async () => {
setIsDataLoading(true);
const fetchedHugeData = await hugeDataFetch();
setData({ ...fetchedHugeData });
setIsDataLoading(false);
}
useEffect(() => {
fetchData();
},[aVariable]);
return [isDataLoading, data];
In the above code, the setIsDataLoading(false)
is getting executed even before setData()
finished in the previous line.
How can I make sure that not happen?
Upvotes: 1
Views: 2014
Reputation:
I tried this
const [data, setData] = useState(null);
const [isDataLoading, setIsDataLoading] = useState(true);
const fetchData = async () => {
setIsDataLoading(true);
await hugeDataFetch().then((_yourResponse) => {
setData({ ..._yourResponse });
setIsDataLoading(false);
});
}
useEffect(() => {
fetchData();
},
[aVariable]);
return [isDataLoading, data];
Upvotes: 0
Reputation: 122
May Be this could work for you...! Simply need to check if your function is returning your data or not... If your returns something and is executed successfully then only it will update your response and set your state data.
const [data, setData] = useState(null);
const [isDataLoading, setIsDataLoading] = useState(true);
const fetchData = async () => {
setIsDataLoading(true);
hugeDataFetch().then((_yourResponse) => {
setData({ ..._yourResponse });
setIsDataLoading(false);
});
}
useEffect(() => {
fetchData();
}, [aVariable]);
return [isDataLoading, data];
Upvotes: 1
Reputation: 66
As ghybs said, state updates are asynchronous, therefore the best solution would be to use another useEffect
that listens to data
and, if not null, calls setIsDataLoading
.
const [data, setData] = useState(null);
const [isDataLoading, setIsDataLoading] = useState(true);
const fetchData = async () => {
setIsDataLoading(true);
const fetchedHugeData = await hugeDataFetch();
setData({ ...fetchedHugeData });
};
useEffect(() => {
fetchData();
}, [aVariable]);
useEffect(() => {
if (data) {
setIsDataLoading(false);
}
}, [data])
return [isDataLoading, data];
Upvotes: 1
Reputation: 348
You need to add another useEffect to view the data state.The code should look like this.
const [data, setData] = useState(null);
const [isDataLoading, setIsDataLoading] = useState(true);
const fetchData = async () => {
setIsDataLoading(true);
const fetchedHugeData = await hugeDataFetch();
setData({ ...fetchedHugeData });
// setIsDataLoading(false);
}
useEffect(() => {
fetchData();
},[aVariable]);
useEffect(() => {
if (data !== null) { setIsDataLoading(false); }
}, [data])
return [isDataLoading, data];
Upvotes: 1