How to wait for state to update without useEffect?

Basically I have custom hook that looks like this:
const [data, setData] = useState<ResponseType | null>(null)
const [isLoading, setLoading] = useState(false)
const [isRunning, setRunning] = useState(false)
const [err, setErr] = useState<Error | null>(null)

const execute = useMemo(
() => async (input: z.infer<InputType>) => {
setRunning(true)
try {
const result = await actionRef.current(input)
setData(result)
setRunning(false)
} catch (e) {
console.log(e)
setErr(e as Error)
setRunning(false)
}
},
[],
)
return {execute, data, isLoading, isRunning, err}
const [data, setData] = useState<ResponseType | null>(null)
const [isLoading, setLoading] = useState(false)
const [isRunning, setRunning] = useState(false)
const [err, setErr] = useState<Error | null>(null)

const execute = useMemo(
() => async (input: z.infer<InputType>) => {
setRunning(true)
try {
const result = await actionRef.current(input)
setData(result)
setRunning(false)
} catch (e) {
console.log(e)
setErr(e as Error)
setRunning(false)
}
},
[],
)
return {execute, data, isLoading, isRunning, err}
Then I call it like this:
const {execute, data} = useFoo()
async function doAction() {
await execute({
id: id,
})
console.log(data) // doesn't work, return stale data instead of waiting for execute to finish updating state
}
const {execute, data} = useFoo()
async function doAction() {
await execute({
id: id,
})
console.log(data) // doesn't work, return stale data instead of waiting for execute to finish updating state
}
Of course I can use useEffect but I prefer not to.
1 Reply
Alan Ibarra-2310
Alan Ibarra-231011mo ago
The reason why it returns stale data is because it closes over the data value for that render. So, whatever value data was when you called execute that is the value that will be logged. You would have to wait for useFoo to re-render in order to see the updated value. You could just return result from execute if you want to see the fresh value after execute or use a ref and update the ref when you update the state in execute.