在我的解决方案中,我将 React Query 的 useQuery
钩子用我自己的钩子包装起来,以具有特定的重试逻辑:
export function useMyQuery(key, queryFn, options = {}) {
const queryClient = useQueryClient();
const query = useReactQuery(key, queryFn, {
...options,
retry: async(count, error) => await retry(count, error, queryClient),
});
return query;
}
retry
函数本身如下:
export async function retry(count, error, queryClient) {
if (error?.statusCode === 401) {
// caught 401, trying to refresh token;
if (await refreshToken(queryClient)) {
queryClient.refetchQueries('fetchSession');
return true;
}
}
// Retry 3 times
return count < 3;
}
最后,我的 fetchSession
查询如下所示:
const { data } = useQuery('fetchSession', () => {
console.log('fetching new session...');
return Auth.currentSession();
})
我的目标是在我成功刷新上面代码中的令牌后触发“fetchSession”查询的重新获取,但是,永远不会重新获取查询,即在刷新令牌后永远不会运行查询正文。除了在 refetchQueries
上使用 queryClient
方法外,我还尝试了 invalidateQueries
没有效果。
答案 0 :(得分:1)
retry
函数不是异步的 - 它希望您返回一个 boolean
,而不是一个 Promise<boolean>
,因此它不起作用。
我会使用 axios 拦截器(如果您正在使用它)或仅在您的 queryFn 中执行此逻辑:
useQuery('fetchSession', async () => {
try {
const { data } = await axios.get(...)
return data
} catch(error) {
if (error.statuscode === 401) {
const token = await refreshToken(queryClient))
const { data } = await axios.get(...) // pass token here? don't know how this works for you :)
return data
} else {
throw error
}
}
})