简体   繁体   中英

Add AddThis to React component

I have a blog implementation based on ReactJS that I would like to integrate with AddThis. I have my social icons and I want to use them. So I'm looking for a way to integrate just the AddThis backend service.

I tried looking around but I was not able to find how to integrate AddThis to a ReactJS component.

I saw this somewhere and it uses a special namespace which to the best of my knowledge is not react friendly.

<div addthis:url='blog_url' addthis:title='blog_title' class="addthis_toolbox">
<a class="addthis_button_facebook">
 <svg ... />
</a>

<a class="addthis_button_twitter">
  <svg ... />
</a>

<a class="addthis_button_linkedin">
  <svg ... />
</a>

<a class="addthis_button_reddit">
  <svg ... />
</a>
</div>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#pubid=xa-4fc9383e1ee05f1b"></script>

Also, I saw this JSFiddle with some information on it, but it is not using ReactJS and does not use custom icons.

Question : Is there any good documentation around AddThis + React?

In addition to the data attribute changes you should use the addthis.layers.refresh() method to dynamically refresh/load your AddThis components:

 render() {
    return (
        <div className="addthis_inline_share_toolbox" 
            data-url={this.props.myurl} 
            data-title="Check out this URL"
            >
        </div>
    );
 }

Then in componentDidMount() :

 componentDidMount() {
     addthis.layers.refresh();
 }

EDIT: The above method is the initial approach i took and does initialise the add this widget however, the widget seems to not update the data-url when the prop is changed. even if i call addthis.layers.refresh(); again after a props update

Dynamic update solution:

In my render method:

// Don't use data attributes
<div className="addthis_inline_share_toolbox"></div>

Use the lifecycle methods:

componentDidMount() {
    addthis.layers.refresh(); // important! init the add this widget
    addthis.update('share', 'url', 'my-initial-url'); // update with initial prop value
}

componentDidUpdate() {
    addthis.update('share', 'url', this.props.myurl); // update with prop value
}

componentWillReceiveProps(nextProps) {
    addthis.update('share', 'url', nextProps.myurl); // update with prop value
}

data-addthis-urldata-addthis-title替换addthis:urladdthis:title data-addthis-title

I put this div in to display the addthis buttons.

<div className="addthis_inline_share_toolbox" data-url={  `http://[Your URL]` } data-title={ `[Your Title]` }></div>

But I also needed to load the javascript after the component mounted or the buttons never display. I assume if you add the javascript to your template that it's loading before the share_toolbox is loaded.

componentDidMount() {
    setTimeout( () => {
      var addthisScript = document.createElement('script');
      addthisScript.setAttribute('src', 'http://s7.addthis.com/js/300/addthis_widget.js#pubid=[your id here]')
      if (document.body) document.body.appendChild(addthisScript)
    });

  },

This was the only info I could find on implementing AddThis in a React app. Eventually helped me get a fix. I am posting my solution for anyone else who comes across this.

Using React Router and AddThis presented some challenges. The key was attaching the addThis javascript methods to window events and not React lifecycle events.

I used react-load-script to asynchronously load the script on the main page of my app, and implemented a callback to initialize the addThis widget and then set state to indicate if addThis was loaded. Then that state gets passed down to the component.

Partial code:

import * as LoadScript from 'react-load-script';

class App extends React.Component {
    constructor(props) {
        this.state = { addThisLoaded: false }
    }

    handleScriptLoad() {
        this.setState({ addthisLoaded: true });
        window.addthis.init();
    }    
    render() {
        return (
            <LoadScript
              url="http://s7.addthis.com/js/300/addthis_widget.js#pubid=ra-xxxxxxxxxxxxxxxx"
              onLoad={this.handleScriptLoad.bind(this)}
            />
            <Switch>
                <Route exact path="/" component={Home} />
                <Route path="/page/:id"
                  render={routeProps => (<Page {...routeProps} addThisLoaded={this.state.addThisLoaded} />)}
                 />
            </Switch>
         );
    }
}

Then in the component that implements the addThis widget I attached the window event listeners to the React lifecycle hooks. The addThisLoaded prop can be used to conditionally render the widget.

export default class Page extends React.Component<Props> {
  componentDidMount() {
    window.addEventListener('load', window.addthis.layers.refresh());
  }

  componentWillUnmount() {
    window.removeEventListener('load', window.addthis.layers.refresh);
  }

  render() {
    const page_url = `YOUR URL GOES HERE`;
    const page_title = `YOUR TITLE GOES HERE`;
    return (
      <div>
        {this.props.addThisLoaded === true && (
            <div className="addthis_inline_share_toolbox" data-url={page_url} data-title={page_title} />
        )}
      </div>
    );
  }
}

If there is a better way to handle it I'd love to hear. The AddThis API docs are sparse. And the fact that it manipulates the DOM to get the desired behavior makes it tricky to incorporate with React Router.

Here is how I did it:

Please, note that I'm using the inline share toolbox.

Thanks @Mark for addthis.update and to @jvoros for react-load-script

import React, { useEffect } from 'react';
import Script from 'react-load-script';

const AddThis = (props) => {
    useEffect(() => {
        if (window.addthis) {
            window.addthis.update('share', 'url', props.url); 
        }
    }, [props.url]);

    const handleAddthisLoaded = () => {
        window.addthis.init();
        window.addthis.update('share', 'url', props.url);
    };

    return (
        <>
        <div className="addthis_inline_share_toolbox"></div>
        <Script
            url="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-xxxxxxxxxxxxxxxx"

            onLoad={handleAddthisLoaded} />
       </>                  
    );
}

export default AddThis;

addthis:url替换为data-url

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM