You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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组件来源

这个treact-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

火山引擎 最新活动