javascript - 在 "Warning: setState(...): Can only update a mounted or mounting component."函数中设置状态时出现 "FB.Event.subscribe()"错误

标签 javascript facebook reactjs

我正在尝试使用 Facebook API 在我的页面上添加 Facebook 登录。当用户单击 Login with Facebook 按钮时,我希望页面重定向到另一个页面。为此,我做了以下工作:

componentDidMount() {
  window.fbAsyncInit = function() {
    FB.init({
      appId            : '1947842912095857',
      autoLogAppEvents : true,
      xfbml            : true,
      version          : 'v2.10'
    });
    FB.AppEvents.logPageView();
    FB.getLoginStatus((response) => {
      if (response.status === 'connected') {
        console.log('Logged in.');
        this.setState({ loggedIn: true });
      }
      else {
      }
    });

  // login callback implementation goes inside the function() { ... } block
  FB.Event.subscribe('auth.statusChange', (response) => {
    if (response.authResponse) {
      console.log('Welcome!  Fetching your information.... ');
      FB.api('/me', (response) => {
        console.log('Good to see you, ' + response.name + '.');
        this.setState({ loggedIn: true });
        // if(!this.state.loggedIn){
        // }
      });
    } else {
      console.log('User cancelled login or did not fully authorize.');
    }
  });
}.bind(this);
  (function(d, s, id){
     var js, fjs = d.getElementsByTagName(s)[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement(s); js.id = id;
     js.src = "//connect.facebook.net/en_US/sdk.js";
     fjs.parentNode.insertBefore(js, fjs);
   }(document, 'script', 'facebook-jssdk'));

    var s = '<div class="fb-login-button" ' +
        'data-scope="public_profile,email" data-size="large" ' +
        'data-show-faces="false" data-auto-logout-link="true" ' +
        'href="javascript:void(0)""></div>';

    var div = document.getElementById('social-login-button-facebook')
    div.innerHTML = s;
}

首先我初始化 Facebook API。然后我调用 FB.getLoginStatus() 来查看用户是否已经登录。在回调中我将 this.state.loggedIn 设置为 true,它工作正常。但是,在 FB.Event.subscribe() 函数中调用 this.setState 函数时出现以下错误:

Warning: setState(...): Can only update a mounted or mounting component.

我试图解决这个问题,我尝试的解决方案是检查用户是否已登录,然后设置状态。

if(!this.state.loggedIn){
  this.setState({ loggedIn: true });
}

然后我摆脱了错误。但我不知道为什么会这样。 有谁知道为什么在 FB.getLoginStatus() 中调用 this.setState() 但在 FB.Event.subscribe() 中不行以及为什么只有在用户尚未登录时才设置状态?

感谢您花时间阅读本文。

最佳答案

这与请求的异步性质有关。虽然组件可能会在某个时刻挂载,但如果有待处理的请求在组件卸载后才完成,那么您将尝试在未挂载的组件上 setState

例如:

class LoginComponent extends Component {

    componentWillMount() {
        // This request will happen whenever the component mounts
        Request.get('/login-token').then(() => {
            dispatch({type: SET_TOKEN, token: 'blah blah'});

            // Whoops, what if there was already a login token 
            // and the user was redirected? This will attempt to set
            // state on a component that has been unmounted due to redirect
            this.setState({loggedIn: true});
        });
    }

    componentWillReceiveProps(props) {
        // This will only redirect if there is already a token
        if (props.token) {
           browserHistory.push('/some-logged-in-page');
        }
    }

    render() {
        return (
            // ...
        );
    }
} 

在此示例中,请求将在每次安装组件时尝试获取 token 。但是我们正在检查 token 是否通过 props 传入,并可能进行重定向。由于请求的异步性质,如果有一个 token 传入,并且用户被重定向,请求仍然会完成并尝试 setState,但是组件已经被卸载到那时。

看看这个 react blog post其中讨论了处理异步请求的问题,并提出了在 componentWillUnmount 中安全取消请求的方法。

关于javascript - 在 "Warning: setState(...): Can only update a mounted or mounting component."函数中设置状态时出现 "FB.Event.subscribe()"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45536031/

相关文章:

javascript - 在函数的参数中设置数组

javascript - 加载 javascript 函数的正确位置在哪里,以便它适用于 ajax 加载的页面?

javascript - 使用 jquery load() 将内容添加到选项卡式导航中

facebook - 如何过渡到 Instagram Graph API for/users/self/media

reactjs - React.js/Redux : setInterval and clearInterval in Reducers

javascript - JS/jQuery跨域访问iframe元素(但js文件同域)

iOS - Swift Facebook Graph 请求完成处理程序 - 表达式类型不明确,没有更多上下文

IOS - 未调用 Facebook SDK fbDidLogin - 初始化 View Controller 。

reactjs - React、Typescript、条件属性

reactjs - 在 react 中带有缓冲区的 Material ui slider