Reputation: 3508
I'm using the useState() hook, and I've found that my app has a bug, because setting the value is asynchronous. So if I have code like this:
const [data, setData] = useState([])
useEffect(() => {
const getData = async () => {
const res = await fetchData()
console.log(data); // []
setData(res.data.hits);
console.log(res.data.hits); // Array full of objects
console.log(data); // Still []
}
getData()
}, [fetchData]);
How can I execute some specific logic only when the new state has actually been set?
Upvotes: 11
Views: 18229
Reputation: 1259
With react 18, useEffect runs twice, but even with that, your logic will work here!
const [data, setData] = useState([])
useEffect(() => {
const getData = async () => {
const res = await fetchData()
setData(res.data.hits);
}
if(!data.length){
// logic for the time, when the state has not been updated yet
getData()
}else if(data.length){
// logic for the time, when the state has been updated
console.log("state is", state)
}
}, [data]); // only use [data], no need to put fetchData in the array
Upvotes: 0
Reputation: 1
You can perform some logic to ensure the "specific logic" you want is executed after your setData is done from that specific call and not from other setData calls,
For example,
const [data, setData] = useState([])
const [runSpecific, setRunSpecific] = useState(false)
useEffect(() => {
const getData = async () => {
const res = await fetchData()
console.log(data); // []
setData(res.data.hits);
setRunSpecific(true);
console.log(res.data.hits); // Array full of objects
console.log(data); // Still []
}
getData()
}, [fetchData]);
useEffect(() => {
if(runSpecific){
"specific Logic" you want to run
}
setRunSpecific(false)
}, [data]);
In essence, every time the data changes, it executes your "specific logic" only when runSpecific
is true, which can only be true from that initial call.
So you need not worry when about other SetData calls.
Upvotes: 0