reactjs - 使用 useMutations [Apollo/React hooks] 重定向后 useQuery 返回 undefined
问题描述
在我的应用程序中,我有 2 个公共路由(登录和注册页面)和一个 PrivateRoute,它使用 JWT 验证 localStorage 中的“auth-token”是否有效。
在我的注册页面中,我使用“useMutations”挂钩来注册用户。我在 LocalStorage 中设置了一个令牌,并通过反应路由器将我发送到主要组件('/'),即聊天。
我做了一个“我”查询,它需要我的“身份验证令牌”才能从数据库中获取特定用户。
问题是,在用户成功注册后被重定向到聊天后,useMutations 太快并返回未定义。如果我刷新页面,它会完美地获取“我”查询。
我已经尝试在重定向上使用 setTimeout,因为它可能是令牌设置得不够快。但事实并非如此。
我试过使用 useLazyQuery 钩子,但这也没有用。它还需要刷新,因为第一次它也给出了 undefined。
/// my register component ///
const Register = props => {
const [createUser] = useMutation(CREATE_USER, {
onCompleted({ createUser }) {
localStorage.setItem('auth-token', createUser.token);
props.history.push('/');
}
});
return (
<InputWrapper>
<h2>Signup for DevChat</h2>
{/* {error !== null && <Alert>{error}</Alert>} */}
<Formik
initialValues={{
userName: '',
email: '',
password: '',
confirmPassword: ''
}}
validationSchema={RegisterSchema}
onSubmit={(values, { resetForm }) => {
createUser({ variables: values });
resetForm({
userName: '',
email: '',
password: '',
confirmPassword: ''
});
}}
>
const UserPanel = () => {
const { data, loading, error } = useQuery(GET_LOGGED_IN_USER, {
context: localStorage.getItem('auth-token')
});
const [toggleOn, setToggleOn] = useState(false);
const handleSignOut = () => {
localStorage.removeItem('auth-token');
///refresh page should redirect to /login
window.location.reload();
};
const toggleDropDown = () => {
setToggleOn(!toggleOn);
};
return (
<ProfileWrapper>
{loading ? <span>Loading ...</span> : console.log(data)}
<ProfileGroup onClick={toggleDropDown}>
<ProfileIcon className='fas fa-user' />
<ProfileTitle>
{/* {loading && called ? <span>Loading ...</span> : console.log(data)} */}
{error ? console.log(error) : null}
</ProfileTitle>
<DropDownIcon
className={toggleOn ? 'fas fa-chevron-up' : 'fas fa-chevron-down'}
/>
/// my console.log(the first time)
undefined
UserPanel.js:95 Error: GraphQL error: jwt malformed
UserPanel.js:91 {}
/// my console.log() after a refresh:
{me: {…}}
me:
age: null
email: "test@gmail.com"
id: "599c5f9a-f97e-4964-a707-138c2159cff8"
userName: "Test"
__typename: "User"
__proto__: Object
想知道我做错了什么...在此先感谢您的帮助和阅读本文... :)
伯特
编辑 1:设置超时在 'props.history.push('/')' 上不起作用
编辑 2:找到解决方案。因为这是我第一个使用 GraphQL 和 Apollo 的项目,所以我不知道 Apollo Boost 就像create-react-app
来自 Apollo 的一样,我需要使用Apollo-Client
(更可定制的包)来配置所有东西。我按照此处的官方文档Apollo Boost
进行了从客户端的迁移。
解决方案
它可能与我的客户端设置有关吗?它使用 apollo-boost 包而不是 apollo-client ...
import React from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
withRouter
} from 'react-router-dom';
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient, { InMemoryCache } from 'apollo-boost';
import Login from './components/auth/Login';
import Register from './components/auth/Register';
import Chat from './components/pages/Chat';
import PrivateRoute from './components/auth/PrivateRoute';
// const cache = new InMemoryCache();
const client = new ApolloClient({
uri: 'http://localhost:4000/',
headers: {
Authorization: `Bearer ${localStorage.getItem('auth-token')}`
}
});
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<Switch>
<PrivateRoute exact path='/' component={Chat} />
<Route path='/register' component={Register} />
<Route path='/login' component={Login} />
</Switch>
</Router>
</ApolloProvider>
);
};
const RootWithAuth = withRouter(App);
推荐阅读
- jquery - 使 Canceled Droppable 元素再次 Droppable
- laravel - 来自 Drupal 时了解 Laravel 中的页面?
- java - 如何将由字段确定的参数列表添加到单个“if”通用语句中?
- angular - 角度插值奇怪的行为
- python - 如何从输入和输出列表中找到函数 f?
- javascript - 将 setState 与来自父元素的道具一起使用
- javascript - Jquery - 附加在html中显示双引号
- angular - (Angular 2/4/5/6) 图像识别
- python - 在片段着色器中访问 3D 数组
- python - pyinstaller 找不到 pyinstaller.exe