Steverino Steverino - 1 month ago 41
React JSX Question

Integrating Facebook Web SDK with ReactJS Component State

I'm getting started with ReactJS, NodeJS, Webpack, and the Facebook SDK for user authentication. All these technologies and their associated software engineering principles/best practices are relatively new to me (even JavaScript is pretty new to me).

I've followed the tutorial here https://developers.facebook.com/docs/facebook-login/web and I've got Facebook authentication working great! But the way this tutorial content is structured, it looks to me like the SDK is designed only to expect the FB status response handlers to be included in the raw page HTML just inside the

<body>
tag. The following in particular references this:

// Load the SDK asynchronously
(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'));


This strategy strikes me as imperfect and hard to integrate with React components. Is there a way to relocate the Facebook login/authentication code and Facebook status update handlers from the HTML, for example, into scripts being bundled with React code via Webpack? Is it possible? Part of the reason for my question is that if I understand correctly, for my Facebook status update handler to be able to update my React components' state, that handler needs to be part of a component to have access to the relevant React component
this.setState(...)
function.

Am I even thinking about this correctly?

Answer

Yes you are right and can very well integrate facebook login with react component.

A sample login component can be like this -

import React from 'react';

class LoginComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {

    };
  }

  loadFbLoginApi() {

        window.fbAsyncInit = function() {
            FB.init({
                appId      : FB_APP_ID,
                cookie     : true,  // enable cookies to allow the server to access
                // the session
                xfbml      : true,  // parse social plugins on this page
                version    : 'v2.5' // use version 2.1
            });
        };

        console.log("Loading fb api");
          // Load the SDK asynchronously
        (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'));
  }

  componentDidMount() {
        this.loadFbLoginApi();
    }

    testAPI() {
      console.log('Welcome!  Fetching your information.... ');
      FB.api('/me', function(response) {
      console.log('Successful login for: ' + response.name);
      document.getElementById('status').innerHTML =
        'Thanks for logging in, ' + response.name + '!';
      });
    }

    statusChangeCallback(response) {
      console.log('statusChangeCallback');
      console.log(response);
      if (response.status === 'connected') {
        this.testAPI();
      } else if (response.status === 'not_authorized') {
          console.log("Please log into this app.");
      } else {
          console.log("Please log into this facebook.");
      }
    }

    checkLoginState() {
      FB.getLoginStatus(function(response) {
        this.statusChangeCallback(response);
      }.bind(this));
    }

    handleFBLogin() {
        FB.login(this.checkLoginState());
        }

    render() {
        return (
                <div>
                    <MyButton
                        classNames = "btn-facebook"
                        id         = "btn-social-login"
                        whenClicked = {this.handleFBLogin}
                        >
                            <span className="fa fa-facebook"></span> Sign in with Facebook
                    </MyButton>
                </div>
               );
    }
}

export default LoginComponent;

When response status received is connected then it means user is logged in via Facebook and you can set state on your component to reflect that. e.g

response.status === 'connected'
this.setState({userLoggedIn:true});

I am using a custom button component (MyButton) in React which you can very easily create.