I am rendering an icon that a user can click on to logout. This icon is rendered under the condition that the user is logged in. I don't want to render it when the user is not logged in. I have this function in an onClick event and whenever the function runs the user is logged out on the backend but the data of the user is still fetched right after. How can this be? I assume that either my async await function is written wrong or it is invalidating the query too quickly? I want to invalidate the user data query so that it refetches and sees that the user is not logged in therefore not rendering the logout icon anymore.
const logoutUser = async () => {
setShowModal(false)
try{
await axios.delete('/logout')
console.log("LoggedOut:")
history.push("/")
queryClient.invalidateQueries('userData')
}catch(error) {
console.log(error.message)
}
}
Picture of my backend handling the logout and getting the user data right after
judging from the attached image, it seems that the delete request comes through and logs out the user. You correctly await the request, which is fine. invalidateQueries is also not "too fast". It will just mark the query as invalid and refetch it if it's active (which it likely is). Now, you go to the backend again which delivers 401. I'm guessing you don't have retries enabled, otherwise, you'd see 3 more requests.
Now what happens is that react-query will never throw away cached data. Even if you have an error, if you've fetched data before, your state will be:
status: 'error',
error: "401 - Unauthorized"
data: staleDataFromTheLastSuccessfulRequest
This is is the stale-while-revalidate and also stale-if-error principles the library is build upon.
After logout, what you likely want is:
queryClient.removeQueries('userData')
this will remove the data from the cache, but not inform observers about it. If you still render something on the screen, it will be there until the next re-render. Likely not a problem when you redirect to the logout screen. Alternatively, you can:queryClient.resetQueries('userData')
this resets the data to its initial state (undefined unless you couple it with initialData), and will also inform active observers, which can result in a refetch. This is likely what you want if you display that icon in a component that is always visible, like a Header.