【发布时间】:2020-08-28 14:27:48
【问题描述】:
我试图在我的项目中实现社交身份验证并收到此错误:
警告:无法对未安装的组件执行 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} />
)
)}/>
)
}
我尝试在我的组件上使用钩子清理,但错误仍然存在。这是我当前的实现的样子:
const FaceookSignIn = () => {
let _isMounted = false
const client = useApolloClient()
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
const [loading, setLoading] = useState(false)
const [callFacebook, data] = useMutation(FACEBOOK_SIGN_IN)
useEffect(()=>{
_isMounted = true
if(!code) return
if(_isMounted) callFacebook({variables: {code: code}})
.then(res=>{
const {error, name, email, accessToken} = res.data.facebookSignIn
if (error) {
alert(`Sign in error: ${error}`);
} else {
client.writeData({
data: {
user: {
name: name,
email: email,
accessToken: accessToken,
__typename: 'User'
}
}
})
setLoading(false)
}
})
.catch(e=>{
console.log(e)
setLoading(false)
})
return ()=> _isMounted = false
},[])
const handleClick = e => {
setLoading(true)
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>
)
}
这种方法有些工作,加载凭据并将用户重定向到经过身份验证的路由,但控制台仍会抛出该错误,并且 ui 有时会在路由之间闪烁。我在这上面花了两天时间,我没有想法。我错过了什么明显的东西吗?
【问题讨论】:
-
_isMounted在这里无效。它不会告诉您您的异步操作callFacebook是否在 组件被卸载后解析。不要使用_isMounted,而是在您的清理处理程序中取消callFacebook请求 - 这样您就不会在组件卸载后调用setLoading(false)。 -
感谢您的回复,但
setLoading不是这里的罪魁祸首,即使在完全删除它之后我收到同样的错误。我也在印象中阿波罗查询在卸载时会自动中止。无论如何我都会尝试取消它并返回
标签: reactjs redirect react-router apollo