我想拥有一个名为AuthRoute的自定义组件,不仅要检查Redux中是否有某些数据,还要用graphql来验证令牌
这是我所做的:
const AuthRoute = ({ component: Component, authUser, ...rest }) => {
const you_must_go_back_to_login = <Route
{...rest}
render={props =>
(<Redirect to={{
pathname: '/user/login',
state: { from: props.location }
}}
/>)
}
/>
const continue_journey = <Route
{...rest}
render={props =>
(<Component {...props} />)
}
/>
const [dest, setDest] = useState(you_must_go_back_to_login)
const [checkThat, setCheckThat] = useState(false)
useEffect(() => {
client.mutate({
mutation: VERIFY_TOKEN_MUTATION,
variables: { token }
}).then(result => {
// setDest(continue_journey)
setCheckThat(true)
})
return () => {
console.log()
};
}, [])
// if(authUser) {
if (checkThat) {
return continue_journey
} else {
return you_must_go_back_to_login;
}
}
这是我需要完成的步骤:
运行突变
setDest为您必须登录或继续旅行的人之一
setCheckThat或类似的东西根据已验证的令牌为真或为假
结果返回目标
现在我遇到了这个错误:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
我将代码更改为此,但是仍然出现相同的错误
const AuthRoute = ({ component: Component, authUser, ...rest }) => {
const you_must_go_back_to_login = (<Route
{...rest}
render={props =>
(<Redirect to={{
pathname: '/user/login',
state: { from: props.location }
}}
/>)
}
/>)
const continue_journey = (<Route
{...rest}
render={props =>
(<Component {...props} />)
}
/>)
// const [dest, setDest] = useState(you_must_go_back_to_login)
const [checkThat, setCheckThat] = useState(false)
useEffect(() => {
let isSubscribed = true
if (isSubscribed) {
getToken();
}
return () => isSubscribed = false
}, []);
const getToken = async (sig) => {
const data = await mutate(VERIFY_TOKEN_MUTATION, { token })
console.log(data)
setCheckThat(true);
console.log(checkThat)
return;
};
return checkThat ? continue_journey : you_must_go_back_to_login;
}
错误是由于比获取数据更早呈现重定向而引起的。
Normlly ...代替useEffect
,您可以使用简单的useQuery
并使用条件loading
或!data
来渲染某些<Loading/>
,以便决定重定向或授予访问权限(呈现重定向或受保护的内容)。
静音通常用于更改远程数据。通过使用查询,您也可以传递变量并返回答案。
我正在使用django graphql jwt,并且问题在于,verifytoken是一个突变
通常/通常由标头传递令牌,API则返回响应或错误(对于丢失/过期的令牌)。通常,您可以选择查询当前用户以进行登录验证。
... 在这种情况下,我们想使用突变
...代替client.mutate
,我们可以使用钩子-useMutation或更好的API example(apollo docs:])-在做出决定之前先访问loading state
const [verifyToken, { data, loading, error }] = useMutation( VERIFY_TOKEN_MUTATION, variables: { token } );
问题?-开始时没有调用变异-loading
在开始时不会为真;-返回的数据。
对于开始时的触发突变,我们可以使用useEffect
,对于返回的数据,我们可以使用onCompleted
处理程序,但是我们可以简单地使用data
-在开始时应该未定义/为空,可用于条件。
这样的事情应该可以工作(我们不需要等待等-data
,loading
,error
将自动更新:]
useEffect(() => {
verifyToken(); // ariables passed earlier, can be passed here
}, []);
if( !data ) return <Loading />
return data.someSuccessVerifiedField ? continue_journey : you_must_go_back_to_login;
警告是不言自明的-
警告:无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复,请取消使用useEffect清理功能中的所有订阅和异步任务。
特别是这部分-
要修复,请取消useEffect清理功能中的所有订阅和异步任务。
您使用的是错误的useEffect
。您不应将您的突变放入useEffect
中。您可以做的是-将变异排除在useEffect
之外。
const [dest, setDest] = useState(you_must_go_back_to_login)
const [checkThat, setCheckThat] = useState(false)
client.mutate({
mutation: VERIFY_TOKEN_MUTATION,
variables: { token }
}).then(result => {
// setDest(continue_journey)
setCheckThat(true)
})
return () => {
console.log()
};
useEffect(() => {
// if(authUser) {
if (checkThat) {
return <continue_journey/>
} else {
return <you_must_go_back_to_login/>;
}
}, [checkThat])
}
因此现在将运行变异,然后设置checkThat
变量。然后将触发useEffect
,它将基于checkThat
的值返回