【发布时间】:2021-10-31 00:01:51
【问题描述】:
我面临下一个问题: 我有一个用于获取 usersData 的 useQuery 钩子
GET_USER_INFO 使用查询
const { data:dataGetUserInfo, loading:loadingQuery, error:errorQuery,refetch } = useQuery(GET_USER_INFO, {variables: {
getUserInfoInfoId: userId
}});
我想在访问令牌过期时刷新访问和刷新令牌。为此,我在 apollo-client.ts 中完成了 errorLink,它在需要时调用了刷新函数,然后调用了我的 GET_USER_INFO useQuery
apollo-client.ts
const getNewToken = () => {
let refreshToken
refreshToken = localStorage.getItem("REFRESH");
return client.mutate({
mutation: REFRESH_TOKEN,
variables:{
refreshTokenRefreshToken : refreshToken,
}
})
.then((res) => {
localStorage.clear();
const { accessToken,refreshToken } = res.data.refreshToken;
localStorage.setItem('REFRESH',refreshToken)
localStorage.setItem('AUTHORIZATION',accessToken)
return res.data;
}).catch((err)=>{
console.log(err)
})
};
const errorLink = onError(
({ graphQLErrors, networkError, operation, forward }) => {
if (graphQLErrors) {
for (let err of graphQLErrors) {
switch (err.extensions?.code) {
case "UNAUTHENTICATED" :
console.log('aa')
return fromPromise(
getNewToken().catch((error) => {
localStorage.clear();
// Handle token refresh errors e.g clear stored tokens, redirect to login
return;
})
)
.filter((value) => Boolean(value))
.flatMap(({accessToken, refreshToken}) => {
const oldHeaders = operation.getContext().headers;
// modify the operation context with a new token
operation.setContext({
headers: {
...oldHeaders,
authorization: `Bearer ${accessToken}`,
},
});
// retry the request, returning the new observable
return forward(operation);
});
}
}
}
}
);
const authLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
authorization: localStorage.getItem("AUTHORIZATION") ? `Bearer ${localStorage.getItem("AUTHORIZATION")}` : "",
},
};
});
const client = new ApolloClient({
link: ApolloLink.from([errorLink,authLink, httpLink]),
})
问题是: 成功刷新令牌后,它不会重新获取我的 useQuery 中的数据
顺便说一句,它又做了一个失败的请求,我不知道为什么
【问题讨论】:
-
你需要使用 useLazyQuery 。例如。您有一个调用 useQuery 的组件,然后一旦组件安装,useQuery 就会运行并从服务器获取数据。但是,如果您在该组件中使用 useLazyQuery 而不是 useQuery,则查询不会运行,并且在组件挂载时不会获取数据。相反,您可以根据您的要求运行查询,例如在您获得刷新令牌后或单击按钮时。
标签: reactjs graphql jwt next.js apollo