如何将Google API与React正确集成

时间:2018-12-07 09:12:08

标签: reactjs google-analytics google-analytics-api

我已经将Google analytics Embed API与我的React应用程序集成在一起,并且能够正确呈现图形。这是我的容器,它通过组件UsersChart呈现折线图:

class StatsContainer extends Component {
    constructor(props) {
        super(props);
        initAnalyticsAPI();
    }

    render() {
      return (
         <Query query={GET_ACCESS_TOKEN}>
          {({ loading: loadingToken, error: errorToken, data: { getAnalyticsAccessToken } }) => (
              <Query query={GET_BASIC_STATS}>
                  {({ loading: loadingStats, error: errorStats, data: { getBasicStats } }) => {
                    if (loadingToken || loadingStats) return 'Loading...';
                    if (errorStats) return `Error! ${errorStats.message}`;
                    else if (errorToken) return `Error! ${errorToken.message}`;

                    const token = getAnalyticsAccessToken;

                    return (
                      <Fragment>
                        <div className="stats-container">
                          {/* ... */
                          <UsersCharts token={token} />
                        </div>
                      </Fragment>
                    );
                  }}
              </Query>
        )}
        </Query>
    );
  }
}

initAnalyticsAPI只是使用官方代码将脚本附加到文档:

function loadGA() {
   /* eslint-disable */
    (function(w,d,s,g,js,fs) {
        g = w.gapi || (w.gapi={});
        g.analytics = { q:[], ready: function(f) { this.q.push(f); }};
        js = d.createElement(s); fs = d.getElementsByTagName(s)[0];
        js.src='https://apis.google.com/js/platform.js';
        fs.parentNode.insertBefore(js,fs);
        js.onload = function() {
            g.load('analytics');
        };
      }(window, document, 'script'));
    /* eslint-enable */
}

export default function initialize() {
    if (typeof window === 'undefined') {
        return false;
    }

    // avoid downloading the library multiple times if it's already defined
    if (_.isEmpty(window.gapi)) {
        loadGA();
    }

    return window.gapi;
}

为简短起见,UsersCharts立即呈现图表使用的容器,而Google API会在就绪后立即加载它:

class UsersCharts extends Component {
    constructor(props) {
        super(props);
        this.chart = null;
    }

    componentWillUnmount() {
       // how to properly unmount it?
    }

    render() {
        const { token } = this.props;
        window.gapi.analytics.ready(() => {
            /**  Authorize the user with an access token obtained server side. */
            window.gapi.analytics.auth.authorize({
                serverAuth: {
                    access_token: token,
                },
            });

            this.chart = new window.gapi.analytics.googleCharts.DataChart({
            query: {
               ...
            },
            chart: {
                ...
            },
         });
        this.chart.execute();
      });

      return (
          <Fragment>
              <div id="chart-container" />
          </Fragment>
      );
    }
}

问题是,当我转到另一部分时,有时会出现以下错误,这意味着由于呈现了另一个组件,因此应用程序内部不再存在图表的容器。我该怎么做才能正确卸下组件?我搜索了一个API,该API可以让我注销图表,或者至少可以捕获错误,但我找不到它。 谢谢

enter image description here

1 个答案:

答案 0 :(得分:1)

通过映射the librarythe component的状态来重构UsersChart,我可以摆脱所有警告:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class UsersCharts extends Component {
    constructor(props) {
        super(props);

        this._isMounted = false;
        this.state = {
            ready: false,
        };
    }

    componentDidMount() {
        this._isMounted = true;
        window.gapi.analytics.ready(() => {
            console.log('Ready to do fireworks');
            if (this._isMounted) {
                 this.setState({ ready: true });
            }
        });
    }

    componentWillUnmount() {
        this._isMounted = false;
    }

    render() {
        const { token } = this.props;

       if (this.state.ready) {
        /**  auth and draw chart */

        this.chart.execute();
       }

       return <div id="chart-container" />;
   }
}