在渲染外使用 apollo client mutate 的问题
problem with using apollo client mutate outside render
我想要一个名为 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 为 you_must_go_to_login 或 continue_journey
之一
setCheckThat 或类似的东西根据令牌是否已验证为真或假
return dest 结果
现在我遇到了这个错误:
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;
}
警告不言自明 -
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.
特别是这部分 -
To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
您使用 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
将被触发,这将 return 基于 checkThat
的值
错误是在获取数据之前呈现重定向导致的。
Normlly ... 而不是 useEffect
您可以使用简单的 useQuery
并使用条件 loading
或 !data
进行渲染一些 <Loading/>
决定重定向或授予访问权限(呈现重定向或受保护的内容)。
突变通常用于改变远程数据。通过使用查询,您也可以传递变量和 return 答案。
I'm using django graphql jwt and the problem is that verifytoken for that is a mutation
在 general/usually 中,令牌由请求头和 API return 响应或错误(对于 missing/expired 令牌)传递。通常您可以选择查询当前用户是否已登录验证。
... 在这种情况下我们要使用突变
... 相反 client.mutate
我们可以使用钩子 - useMutation or better API example (apollo docs :] ) - 在做出决定之前访问 loading state
const [verifyToken, { data, loading, error }] = useMutation( VERIFY_TOKEN_MUTATION, variables: { token } );
有问题?
- 开始时不调用突变 - loading
不会在开始时为真;
- returned 数据。
为了在开始时触发突变我们可以使用 useEffect
,对于 returned 数据我们可以使用 onCompleted
处理程序但我们可以简单地使用 data
- 应该是 undefined/nulled 开始时,可用于条件。
像这样的东西应该可以工作(我们不需要等待等 - 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;
我想要一个名为 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 为 you_must_go_to_login 或 continue_journey
之一
setCheckThat 或类似的东西根据令牌是否已验证为真或假
return dest 结果
现在我遇到了这个错误:
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;
}
警告不言自明 -
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.
特别是这部分 -
To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
您使用 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
将被触发,这将 return 基于 checkThat
错误是在获取数据之前呈现重定向导致的。
Normlly ... 而不是 useEffect
您可以使用简单的 useQuery
并使用条件 loading
或 !data
进行渲染一些 <Loading/>
决定重定向或授予访问权限(呈现重定向或受保护的内容)。
突变通常用于改变远程数据。通过使用查询,您也可以传递变量和 return 答案。
I'm using django graphql jwt and the problem is that verifytoken for that is a mutation
在 general/usually 中,令牌由请求头和 API return 响应或错误(对于 missing/expired 令牌)传递。通常您可以选择查询当前用户是否已登录验证。
... 在这种情况下我们要使用突变
... 相反 client.mutate
我们可以使用钩子 - useMutation or better API example (apollo docs :] ) - 在做出决定之前访问 loading state
const [verifyToken, { data, loading, error }] = useMutation( VERIFY_TOKEN_MUTATION, variables: { token } );
有问题?
- 开始时不调用突变 - loading
不会在开始时为真;
- returned 数据。
为了在开始时触发突变我们可以使用 useEffect
,对于 returned 数据我们可以使用 onCompleted
处理程序但我们可以简单地使用 data
- 应该是 undefined/nulled 开始时,可用于条件。
像这样的东西应该可以工作(我们不需要等待等 - 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;