我正在尝试使用Google Sheets API将其包含在我的网络应用程序中,但始终收到错误消息,指出未定义gapi库。我尝试使用ComponentDidMount生命周期方法甚至在该方法中使用超时来延迟对服务器的请求,但是我一直收到相同的错误。如何在我的应用程序中定义供使用的gapi库?

import React from 'react';
var CLIENT_ID = '';
var SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"];


export default class MyNavbar extends React.Component {

  constructor(props) {
    super(props);
  }

  componentDidMount(){
     this.checkAuth();

   }

      /**
       * Check if current user has authorized this application.
       */
    checkAuth(){
        gapi.auth.authorize(
          {
            'client_id': CLIENT_ID,
            'scope': SCOPES.join(' '),
            'immediate': true
          }, this.handleAuthResult());
      }

      /**
       * Handle response from authorization server.
       *
       * @param {Object} authResult Authorization result.
       */
      handleAuthResult(authResult) {
        var authorizeDiv = document.getElementById('authorize-div');
        if (authResult && !authResult.error) {
          // Hide auth UI, then load client library.
          authorizeDiv.style.display = 'none';
          loadSheetsApi();
        } else {
          // Show auth UI, allowing the user to initiate authorization by
          // clicking authorize button.
          authorizeDiv.style.display = 'inline';
        }
      }

      /**
       * Initiate auth flow in response to user clicking authorize button.
       *
       * @param {Event} event Button click event.
       */
     handleAuthClick(event) {
        gapi.auth.authorize(
          {client_id: CLIENT_ID, scope: SCOPES, immediate: false},
          handleAuthResult);
        return false;
      }

      /**
       * Load Sheets API client library.
       */
     loadSheetsApi() {
        var discoveryUrl =
            'https://sheets.googleapis.com/$discovery/rest?version=v4';
        gapi.client.load(discoveryUrl).then(listMajors);
      }

      /**
       * Print the names and majors of students in a sample spreadsheet:
       * https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
       */
      listMajors() {
        gapi.client.sheets.spreadsheets.values.get({
          spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms',
          range: 'Class Data!A2:E',
        }).then(function(response) {
          var range = response.result;
          if (range.values.length > 0) {
            appendPre('Name, Major:');
            for (i = 0; i < range.values.length; i++) {
              var row = range.values[i];
              // Print columns A and E, which correspond to indices 0 and 4.
              appendPre(row[0] + ', ' + row[4]);
            }
          } else {
            appendPre('No data found.');
          }
        }, function(response) {
          appendPre('Error: ' + response.result.error.message);
        });
      }

      /**
       * Append a pre element to the body containing the given message
       * as its text node.
       *
       * @param {string} message Text to be placed in pre element.
       */
      appendPre(message) {
        var pre = document.getElementById('output');
        var textContent = document.createTextNode(message + '\n');
        pre.appendChild(textContent);
      }


   render(){
      return (
        <div>
          <h1>Hello World My Name Is Justin 2</h1>
          <div id="authorize-div"></div>
          <pre id="output"></pre>
        </div>
      );
    }
}

最佳答案

在这里试试。

import React from 'react';
import asyncLoad from 'react-async-loader'; // for loading script tag asyncly `npm i --save react-async-loader`

const CLIENT_ID = '';
const SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"];

// For making gapi object passed as props to our component
const mapScriptToProps = state => ({
   // gapi will be this.props.gapi
   gapi: {
      globalPath: 'gapi',
      url: 'https://your-gapi-url'
   }
});

@asyncLoad(mapScriptToProps)
class MyNavbar extends React.Component {

  constructor(props) {
    super(props);
    this.gapi = null;
    // You need to bind methods to this class's object context. (i.e this)!
    this.checkAuth = this.checkAuth.bind(this);
    this.handleAuthResult = this.authResult.bind(this);
    this.handleAuthClick = this.handleAuthClick.bind(this);
    this.loadSheetsApi = this.loadSheetsApi.bind(this);
    this.listMajors = this.listMajors.bind(this);
  }

  componentDidMount() {
    // Check is gapi loaded?
    if (this.props.gapi !== null) {
       this.checkAuth();
    }
  }

  componentWillReceiveProps({ gapi }) {
    if (gapi!== null) {
      this.checkAuth();
    }
  }

   /**
   * Check if current user has authorized this application.
   */
  checkAuth() {

    // this will give you an error of gapi is not defined because there is no
    // reference of gapi found globally you cannot access global object which are
    // not predefined in javascript( in this case its window.gapi ).
    // properties added by Programmer cannot be accessed directly( if it's not in the same file as well as the same scope!) in commonjs modules. Because they
    // don't' run in a global scope. Any variable in another module which is not
    // exported, will not be available to other modules.

    this.gapi = window.gapi; // you can do like this. Now you can access gapi in all methods if this class.
    this
        .gapi
        .auth
        .authorize({
            'client_id': CLIENT_ID,
            'scope': SCOPES.join(' '),
            'immediate': true
        }, this.handleAuthResult());
  }

   /**
   * Handle response from authorization server.
   *
   * @param {Object} authResult Authorization result.
   */
  handleAuthResult(authResult) {
    var authorizeDiv = document.getElementById('authorize-div');
    if (authResult && !authResult.error) {
        // Hide auth UI, then load client library.
        authorizeDiv.style.display = 'none';
        loadSheetsApi();
    } else {
        // Show auth UI, allowing the user to initiate authorization by clicking
        // authorize button.
        authorizeDiv.style.display = 'inline';
    }
  }

  /**
   * Initiate auth flow in response to user clicking authorize button.
   *
   * @param {Event} event Button click event.
   */
  handleAuthClick(event) {
    // gapi.auth.authorize(  here also gapi is not defined
     this
        .gapi
        .auth
        .authorize({
            client_id: CLIENT_ID,
            scope: SCOPES,
            immediate: false
        }, handleAuthResult);
    return false;
  }

  /**
   * Load Sheets API client library.
   */
  loadSheetsApi() {
    var discoveryUrl = 'https://sheets.googleapis.com/$discovery/rest?version=v4';
    // also will give your error
    // for gapi being not defined.
    // gapi.client.load(discoveryUrl).then(listMajors);
    this
        .gapi
        .client
        .load(discoveryUrl)
        .then(listMajors);
  }

  /**
   * Print the names and majors of students in a sample spreadsheet:
   * https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
   */
  listMajors() {
    this.gapi
        .client
        .sheets
        .spreadsheets
        .values
        .get({spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms', range: 'Class Data!A2:E'})
        .then(function (response) {
            var range = response.result;
            if (range.values.length > 0) {
                appendPre('Name, Major:');
                for (i = 0; i < range.values.length; i++) {
                    var row = range.values[i];
                    // Print columns A and E, which correspond to indices 0 and 4.
                    appendPre(row[0] + ', ' + row[4]);
                }
            } else {
                appendPre('No data found.');
            }
        }, function (response) {
            appendPre('Error: ' + response.result.error.message);
        });
  }

 /**
   * Append a pre element to the body containing the given message
   * as its text node.
   *
   * @param {string} message Text to be placed in pre element.
   */
  appendPre(message) {
    // as you can see. You are accessing window.document as document.
    // its fine because its defined in javascript (implicitly),
    // not explicitly by programmer(here you!).
    var pre = document.getElementById('output');
    var textContent = document.createTextNode(message + '\n');
    pre.appendChild(textContent);
  }

  render() {
    return (
        <div>
            <h1>Hello World My Name Is Justin 2</h1>
            <div id="authorize-div"></div>
            <pre id="output"></pre>
        </div>
    );
  }
}

export default MyNavbar;

关于javascript - “未定义GAPI”消息,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40112947/

10-08 23:22