I have 2 custom hooks. 1 to PUT data, the other to GET the data. I need to retrieve the data immediately after it has been PUT to route the user and handle any errors. With what I have below, the actions happen to fast and GET happens before PUT. Any way around this?
const { update, fetch, data, loading, success } = useFoo(data);
const OnClickHandler = () => {
update();
if (success === 200) {
fetch();
// do some checks and if ok route
} else {
// do something else
}
};
const fetch = useCallback(() => {
setLoading(true);
axios({
url: url,
headers: foo,
method: "get"
})
.then((response) => {
setLoading(false);
setSuccess(response.status);
setData(response.data);
})
.catch((error) => {
setLoading(false);
});
}, [setSuccess]);
const update = useCallback(() => {
setLoading(true);
axios({
url: url,
headers: foo,
method: "put",
data: data,
responseType: "json"
})
.then((response) => {
setLoading(false);
setSuccess(response.status);
console.log(response);
})
.catch((error) => {
setLoading(false);
});
}, [data]);
CodePudding user response:
If you want to wait for the end of certain calls, you must mark the function as async and wait for the function call.
I tried to anticipate the structure of your useFoo() hook, and here are my changes:
const useFoo = (data) => {
const [ loading, setLoading ] = React.useState(false)
const [ success, setSuccess ] = React.useState()
const [ data, setData ] = React.useState()
const [ error, setError ] = React.useState()
const fetch = React.useCallback(async () => {
setLoading(true)
await axios({
url, // TODO: pass your url
headers: {}, // TODO: pass your headers
method: 'get'
})
.then((response) => {
setSuccess(response.status)
setData(response.data)
})
.catch((error) => {
setError(error)
})
.finally(() => setLoading(false))
}, [ setSuccess ])
const update = React.useCallback(
async () => {
setLoading(true)
await axios({
url, // TODO: pass your url
headers: {}, // TODO: pass your headers
method: 'put',
data,
responseType: 'json'
})
.then((response) => {
setSuccess(response.status)
})
.catch((error) => {
setError(error)
})
.finally(() => setLoading(false))
},
[ data ]
)
return {
data,
fetch,
loading,
success,
update,
error
}
}
The component that uses the hook might look something like this:
const YourComponent = () => {
const { update, fetch, data, success } = useFoo(foo)
const onClickHandler = async () => {
await update()
if (success === 200) {
await fetch()
// do some checks and if ok route
} else {
// do something else
}
}
return null
}
The await
keyword forces the function to block until the function call is finished.