React中react-facebook-login生命周期问题排查求助
解决方案:React Facebook登录按钮的生命周期错误与组件问题
嘿,我仔细看了你的代码和遇到的问题,咱们一步步拆解解决:
1. 先修复Facebook按钮的disabled属性缺失问题
你会发现Google登录按钮里给IoLogoGoogle传递了disabled={renderProps.disabled},但Facebook的IoLogoFacebook没加这个属性。这就导致当Facebook登录流程处于加载状态时,按钮还能被重复点击,进而触发多次异步请求;当组件卸载(比如登录成功后跳转页面)时,未完成的回调还在执行,就会抛出生命周期相关错误。
把Facebook按钮的代码改成这样:
<IoLogoFacebook onClick={renderProps.onClick} disabled={renderProps.disabled} />
2. 处理组件卸载后的异步回调问题
即使加了disabled,还是可能存在组件卸载后回调继续执行的情况(比如用户在登录请求过程中手动跳转页面)。咱们可以用useState跟踪组件挂载状态,在回调里判断组件是否还挂载,再执行后续操作:
首先在组件里添加状态和清理逻辑:
const [isMounted, setIsMounted] = useState(true); useEffect(() => { return () => { setIsMounted(false); // 组件卸载时标记为未挂载 }; }, []);
然后修改responseFacebook函数:
const responseFacebook = (response) => { if (!isMounted) return; // 组件已卸载,直接终止后续操作 const emailFromFacebook = response.email; facebookLogin(emailFromFacebook, history); };
3. 关于你提到的t组件来源
这个t是react-facebook-login库内部经过压缩/混淆后的组件名称,属于库的内部实现,你完全不需要关心它的具体来源——只要解决上面两个问题,相关的生命周期错误应该就会消失。
修改后的完整组件代码
import React, { useState, useEffect } from 'react'; import './SignIn.css'; import { IoLogoGoogle, IoLogoFacebook } from 'react-icons/io'; import { connect } from 'react-redux'; import { useHistory, Link } from 'react-router-dom'; import { LoginAction, GoogleLoginAction, FacebookLoginAction } from '../../redux/User/User.actions'; import { GoogleLogin } from 'react-google-login'; import FacebookLogin from 'react-facebook-login/dist/facebook-login-render-props' function SignIn(props) { const { googleLogin, facebookLogin } = props; const history = useHistory(); const [isMounted, setIsMounted] = useState(true); useEffect(() => { return () => { setIsMounted(false); }; }, []); const responseGoogle = (response) => { const email = response.profileObj; googleLogin(email, history); } const responseFacebook = (response) => { if (!isMounted) return; const emailFromFacebook = response.email; facebookLogin(emailFromFacebook, history); } return ( <div className="login-container"> <div className="sign-social-media-icons"> <div className="social-media-icon"> <GoogleLogin clientId="appId" render={renderProps => ( <IoLogoGoogle onClick={renderProps.onClick} disabled={renderProps.disabled} /> )} buttonText="Login" onSuccess={responseGoogle} onFailure={responseGoogle} cookiePolicy={'single_host_origin'} /> </div> <div className="social-media-icon"> <FacebookLogin appId="appId" callback={responseFacebook} fields="first_name, last_name, email" scope="public_profile, email" returnScopes={true} render={renderProps => ( <IoLogoFacebook onClick={renderProps.onClick} disabled={renderProps.disabled} /> )} /> </div> </div> </div> ) }; const mapDispatchToProps = (dispatch) => { return { googleLogin: (googleLoginState, history) => { dispatch(GoogleLoginAction(googleLoginState, history)); }, facebookLogin: (facebookLoginState, history) => { dispatch(FacebookLoginAction(facebookLoginState, history)); }, }; }; export default connect( null, // 注意:connect第一个参数即使不用也要传null,避免潜在问题 mapDispatchToProps )(SignIn);
内容的提问来源于stack exchange,提问作者sam1024




