使用apollo客户端在外部渲染时发生问题的问题

问题描述 投票:0回答:2

我想拥有一个名为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;
  }
}

这是我需要完成的步骤:

  1. 运行突变

  2. setDest为您必须登录或继续旅行的人之一

  3. setCheckThat或类似的东西根据已验证的令牌为真或为假

  4. 结果返回目标

现在我遇到了这个错误:

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;
}
reactjs graphql react-apollo apollo-client use-effect
2个回答
0
投票

错误是由于比获取数据更早呈现重定向而引起的。

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-在开始时应该未定义/为空,可用于条件。

这样的事情应该可以工作(我们不需要等待等-dataloadingerror将自动更新:]

useEffect(() => {
  verifyToken(); // ariables passed earlier, can be passed here
}, []);

if( !data ) return <Loading />

return data.someSuccessVerifiedField ? continue_journey : you_must_go_back_to_login;

0
投票

警告是不言自明的-

警告:无法在已卸载的组件上执行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的值返回

© www.soinside.com 2019 - 2024. All rights reserved.