I am passing the access token used as Bearer token in request headers inside the query function through useContext hook. But when the access token is refreshed after some time, react query keeps using the old access token in the query function.
This is the component using react-query:
const Profile = () => {
const { fetchUser} = useAppContext();
const { data, isLoading, isError, error } = useQuery(
['users'],
fetchUser
);
//...
}
This axios intercepter is passed with the context:
const authFetch = axios.create({
baseURL: '/api/v1',
headers: {
Authorization: `Bearer ${state.accessToken}`,
},
});
authFetch.interceptors.response.use(
(response) => response,
async (error) => {
const status = error?.response?.status;
if (status === 401) {
const config = error.config;
const accessToken = await refreshAccessToken();
config.headers['Authorization'] = `Bearer ${accessToken}`;
return axios.request(config);
}
return Promise.reject(error);
}
);
(
await refreshAccessToken() gets a new access token from the server and updates it in the context state, then returns it back.
)
The function used inside useQuery is also passed with the context:
const fetchUser = async () => {
const { data } = await authFetch.get('/users');
return data;
};
But when the access token is refreshed, useQuery still uses the old access token in the query function. How can I structure my app so that the query uses the new token each time after update?
The problem is that you're closing over the token in your queryFn. You're not showing this but I guess state.accessToken comes from useContext or so.
Generally, everything you use inside the queryFn should be part of the queryKey. So one way to fix it would be to add the token to the queryKey. By combining this with keepPreviousData: true, you will keep seeing the old data while the new cache entry is created.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With