Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I embed a facebook send button in my react app?

I have a client side rendered react app. I want to display a facebook send button on my page.

The instructions given on the developer page do not tell me how to do it

https://developers.facebook.com/docs/plugins/send-button#configurator

Plus, I did not find an npm compatible package released by facebook for their SDK. So how does one go about including the SDK in a react app?

EDIT: I tried using some async loader in react.

import React, { Component } from 'react';
import scriptLoader from 'react-async-script-loader';

@scriptLoader(
  'https://connect.facebook.net/es_ES/sdk.js#xfbml=1&version=v2.5',
)
class FacebookSendButton extends Component {

  componentDidMount() {
    const { isScriptLoaded, isScriptLoadSucceed } = this.props;
    if (isScriptLoaded && isScriptLoadSucceed) {
      console.log('script load success from didMount');
    }
  }

  componentWillReceiveProps({ isScriptLoaded, isScriptLoadSucceed }) {
    if (isScriptLoaded && !this.props.isScriptLoaded) { // load finished
      if (isScriptLoadSucceed) {
        console.log('script load success from receiveProps');
      }
    }
  }

  render() {
    return (

      <div>
       BEFORE FB ROOT.
      <div className="fb-send"
        dataHref="http://www.your-domain.com/your-page.html"
        dataLt ayout="button_count"
      />
      <div id="fb-root"></div>
    </div>
    );
  }
}

export default FacebookSendButton;

This does not render a facebook send button.

like image 521
sheki Avatar asked Mar 15 '16 18:03

sheki


1 Answers

Once the FB SDK loads, it parses through the entire markup of the page to find elements with the special fb-* classes. Since the FB script is loading at the time your module is initialized, it's likely that the SDK loads before you end up mounting your component. To get it to re-process the DOM, you'd want to add something like the following to your componentDidMount:

if (window.FB) {
  // Read the entire document for `fb-*` classnames
  FB.XFBML.parse();
}

Of course, you probably don't want to parse the entire document every time a send button mounts. You can narrow the scope of the search by creating a ref to the DOM node you want to search, and then passing that to the parse() method.

componentDidMount() {
  const { isScriptLoaded, isScriptLoadSucceed } = this.props;
  if (isScriptLoaded && isScriptLoadSucceed && window.FB) {
    window.FB.XFBML.parse(this._scope);
  }
}

componentWillReceiveProps({ isScriptLoaded, isScriptLoadSucceed }) {
  if (isScriptLoaded && !this.props.isScriptLoaded) { // load finished
    if (isScriptLoadSucceed && window.FB) {
      window.FB.XFBML.parse(this._scope);
    }
  }
}

render() {
  return (
    <div ref={(s) => this._scope = s}>
      <div id="fb-root"></div>
      <div
        className="fb-send"
        data-href="http://www.your-domain.com/your-page.html"
        data-layout="button_count"
      />
    </div>
  );
}

You'll notice I use the new method of functional refs here. Named refs (eg ref="somestr") are being deprecated & discouraged by the React team.

I have a hacky version of this working from the following gist: https://gist.github.com/andrewimm/9fdd0007c3476446986a9f600ba4183f

like image 189
Andrew I Avatar answered Sep 25 '22 19:09

Andrew I