Apollo客户端(反应)-未安装组件上的Cant更新状态

时间:2020-05-12 16:31:59

标签: reactjs redirect react-router apollo

我试图在我的项目中实施社交身份验证并收到此错误:

警告:无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复,请取消使用useEffect清理功能中的所有订阅和异步任务。 在FaceookSignIn中(由Socials创建) ...

有问题的组件从Facebook接收代码,该代码被放入url中以进行重定向。

这是路线:

定义为:

<PublicRoute exact path='/:callback?' component={Auth}/>

我尝试在组件上使用钩子清理,但错误仍然存​​在。这是我当前的实现方式:

export const PublicRoute = ({component: Component, ...rest}) => {
  const {client, loading, data} = useQuery(GET_USER, {fetchPolicy: 'cache-only'})
  let isAuthenticated = !!data.user.accessToken

  return (
    <Route {...rest} component={(props)=>(
      isAuthenticated ? (
        <Redirect to='/home' />
      ) : (
        <Component {...props} />
      )
    )}/>
  )  
}

这种方法有些奏效,凭证被加载,用户被重定向到经过身份验证的路由,但控制台仍然抛出该错误,并且UI在路由之间有时会闪烁。我已经花了最后两天的时间,而我却没有任何想法。我缺少明显的东西吗?

1 个答案:

答案 0 :(得分:0)

好,终于弄清楚了,原来我不应该从阿波罗钩子上劫持逻辑,并且要小心数据的处理方式。我假设变异钩子自行更新客户端状态,.then()块在客户端更新和卸载组件之前已解决。也许有人可以澄清?

如果有人有兴趣,这里无论如何都会更新代码:

const FaceookSignIn = (props) => {
  const appId = '187856148967924'
  const redirectUrl = `${document.location.protocol}//${document.location.host}/facebook-callback`
  const code = (document.location.pathname === '/facebook-callback') ? querystring.parse(document.location.search)['?code'] : null

//moved data handling logic to hooks optional callback
const [callFacebook, {client, data, loading, error, called}] = useMutation(FACEBOOK_SIGN_IN, {onCompleted: (data)=>{
    const {name, email, accessToken} = data.facebookSignIn
    client.writeData({
      data: {
        user: {
          name: name,
          email: email,
          accessToken: accessToken,
          __typename: 'User'
        }
      }
    })
  }})

  if(code && !called) {
    callFacebook({variables: {code: code}})
  }

  const handleClick = e => {
    e.preventDefault()
    window.location.href = `https://www.facebook.com/v2.9/dialog/oauth?client_id=${appId}&redirect_uri=${encodeURIComponent(redirectUrl)}`;
  }

  return (
    <a className="login-options__link" href='/facebook-login' onClick={handleClick}>
      {loading ? <p>loading...</p> : <img className="social-link__icon" src={fb.default} id="facebook" /> }
    </a>
  )
}