【发布时间】:2021-02-10 03:19:28
【问题描述】:
我正在使用短期 JWT 令牌来访问我的 API;令牌需要每 10 分钟左右获取一次。我的根 App 组件会在某个时间间隔内获取令牌,将其设置为本地状态并传递给我的所有组件都可以访问它的上下文。
function App() {
const queryClient = new QueryClient()
const [auth, setAuth] = useState({
isValid: null,
token: null,
user: null
})
//Get User and API Token
useEffect(() => {
const fetchToken = async () => {
try {
const fetchItem = await fetch(
'http://someLocalHost:5000/user',
{
credentials: 'include'
}
)
const fetchResponse = await fetchItem.json();
console.log(fetchResponse)
if (fetchItem.status === 200) {
setAuth({
isValid: true,
token: fetchResponse['token'],
user: fetchResponse['user']
});
}
} catch {
setAuth({isValid: false});
}
};
var intervalCall;
if (auth.isValid === true) {
intervalCall = setInterval(fetchToken, 200000);
} else if (auth.isValid === false) {
return
} else {
fetchToken();
}
return () => {
clearInterval(intervalCall);
};
}, [auth.isValid]);
const authContext = {
user: auth.user,
token: auth.token,
login: (props) => {
setAuth({
isValid: true,
token: props.token,
user: props.user,
})
},
logout: () => {
setAuth({
isValid: false
})
}
}
return (
<div>
<QueryClientProvider client={queryClient}>
<AuthContext.Provider value={authContext}>
<Router>
<Nav />
<main>
<Switch>
<Route path="/" exact component={Index} />
</Switch>
</main>
</Router>
</AuthContext.Provider>
</QueryClientProvider>
</div>
);
}
export default App
我使用 react-query 来获取、存储和更新 API 数据。我的组件通常看起来像这样:
function Index() {
const auth = useContext(AuthContext);
);
const usersQuery = useQuery(
'users',
() => fetchData({url: '/users', token: auth.token})
);
return (
<div>
<UserList list={usersQuery.data} />
<NewUser />
</div>
)
}
export default Index
我真的很喜欢 invalidateQueries 重新获取数据的能力。 New User 组件使用突变,然后使“用户”查询无效。
function NewUser() {
const auth = useContext(AuthContext);
const queryClient = useQueryClient()
const newUserMutation = useMutation(formData => fetchPUT({
url: 'new_user',
type: 'PUT',
token: auth.token,
formData: formData
}), {
onSuccess: () => {
queryClient.invalidateQueries('users');
}
});
const addUser = (user_id) => {
var fetchData = new FormData();
fetchData.append('user_id', user_id);
newUserMutation.mutate(fetchData);
};
return (
<div>
<button onClick={() => addUser('someUserID')}>Create New User</button>
</div>
)
}
export default NewUser
这很好用,直到 200000 毫秒过去,我的根组件获取一个新的身份验证令牌并更新上下文。一旦上下文更新invalidateQueries 不会触发并且refetchOnWindowFocus 不会触发。只有刷新修复它。我假设它是由 react-query 散列查询键的方式引起的,所以我尝试将身份验证令牌和 url 添加到查询键数组中,然后在我的 fetch 函数中使用queryKeys。
const usersQuery = useQuery(
['users', {url: '/users', token: auth.token}],
fetchData
);
但无济于事。有谁知道是什么原因造成的?是我的结构吗?每次上下文更改起作用时都重新安装 Index 组件,但是对于许多嵌套组件,这将变得很痛苦。
这是我的组件树的简化结构,只显示相关代码,实际结构更加嵌套和复杂。
【问题讨论】:
标签: reactjs react-router react-context react-query