我们使用react-query
从API中获取数据。对于每个API调用,都有一个具有不同查询键的单独钩子,但它们都使用相同的函数callApi()
,该函数将api url作为参数来获取数据。
在callAPI()
钩子中,我们有从authState获取要使用的auth令牌的逻辑。(代码如下)
const useAxios = (baseUrl = config.API_URL) => {
const history = useHistory()
const [{ accessToken }] = useAuthState()
const callApi = useCallback(
async ({ headers, ...rest }) => {
try {
const { data } = await axios({
baseURL: baseUrl,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
...headers,
},
...rest,
validateStatus: (status) => status >= 200 && status <= 299,
})
return data
} catch (err) {
if (err && err.response && err.response.status === 401) {
history.push(`${appConfig.APP_SUBPATH}/sessionExpired`)
} else if (err && err.response && err.response.status === 503) {
history.push(`${appConfig.APP_SUBPATH}/underMaintenance`)
}
throw err
}
},
[accessToken],
)
return callApi
}
export default useAxios
export const useGetItems = () => {
const callApi = useAxios()
return useQuery(ALL_ITEMS_KEY, () =>
callApi({
method: 'GET',
url: 'api/v1/items',
}).then((data) => data.data),
)
}
问题:令牌刷新后,react-query仍然使用旧令牌重新获取无效的查询,导致***401 UnAuthorized***,尽管状态中的令牌也已更新。
为什么react-query在刷新后仍在使用旧的token?如何防止react-query使用旧的token?
**编辑:**我知道react-query不会因为token更新而自动重取,但是如果查询被标记为无效,则会自动重取,如下图所示。在这种情况下,它会使用第一次调用时使用的旧过期token
queryCache.invalidateQueries((x) => x.queryKey.includes(ALL_ITEMS_KEY))
2条答案
按热度按时间hpcdzsge1#
您在queryKey中没有访问令牌:
所以ReactQuery无法理解它应该在数据更改时重新获取数据。将其添加到查询键:
如果没有标记,您也可以选择禁用查询。
kuuvgm7e2#
你在React中遇到了一个陈旧的闭包问题,这是因为你的React依赖(令牌)不是
queryKey
的一部分。当重新获取发生时,queryFunction从上次更改键的时间开始使用,因此它仍然可以看到闭包中的旧令牌。
这就是为什么在queryKey中包含所有依赖项如此重要的原因。
我有一个关于闭包的两部分blopost系列,也许这有助于更好地理解这个问题:
现在令牌是一个“特殊”的情况下,我不想将它们包含在QueryKey中。问题是:为什么token来自
useAuthState
?我猜这是react上下文,但为什么token首先需要存储在react上下文中?从react查询的Angular 来看,没有必要用新的token通知/重新呈现您的组件,除非您也在queryKey中包含该token。如果您已经在使用axios,那么更好的处理令牌的地方是一个axios拦截器。