【问题标题】:React- only run file once external js file loaded (gapi not defined)React- 仅在加载外部 js 文件后才运行文件(未定义 gapi)
【发布时间】:2017-03-29 10:49:33
【问题描述】:

我正在尝试将 gmail API 与 React.js 一起使用。

我不断收到错误消息“未定义 gapi”。我相信在我的mail.js 文件运行后我的 HTML 中的client.js 文件正在加载?

我该如何解决这个问题?

Index.html

...
<script src="https://apis.google.com/js/client.js"></script>

Index.js

import './Mail.js';

Mail.js

import { createAction, handleActions } from 'redux-actions'

const CLIENT_ID = '1.apps.googleusercontent.com'
const SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']

export const SET_GMAIL_CREDENTIALS = 'SET_GMAIL_CREDENTIALS'
export const CHANGE_LOADING = 'CHANGE_LOADING'
export const SET_GMAIL_LABELS = 'SET_GMAIL_LABELS'
export const SELECT_GMAIL_LABEL = 'SELECT_GMAIL_LABEL'
export const SET_GMAIL_EMAILS = 'SET_GMAIL_EMAILS'

let defaultState = {
  profile: {
    emailAddress: ''
  },
  loading: true,
  labels: [],
  currentLabel: null,
  emails: []
}

export const connect = () => {
  return (dispatch, getState) => {
    dispatch(turnLoadingOn())
    gmailAuth(false, populateCredentials(dispatch), clearCredentials(dispatch))
  }
}...

【问题讨论】:

  • 你的 gmail-api 脚本标签在你捆绑的 react/application 脚本标签之后吗?

标签: javascript reactjs gmail-api


【解决方案1】:

我认为你是对的。我处理这些情况的方法是从 React 加载外部 JS 文件并在 Promise 中使用它。

所以你的流程应该是这样的:

  1. 响应应用加载
  2. React 应用在 HTML 中注入您的文件
  3. 在第 2 步的回调或 .then() 中执行您的操作

创建一个辅助函数。将其放在helpers/load-script 之类的文件夹中。下面是该文件中应包含的所有代码:

export default function loadScript(url, cb) {

      var scr = document.createElement('script');
      scr.type = 'text/javascript';

      if (scr.readyState) { // IE
        scr.onreadystatechange = function() {
          if (scr.readyState ==`loaded' || scr.readyState ==='complete') {
            scr.onreadystatechange = null;
            cb();
          }
        };
      } else { // Others
        scr.onload = cb;
      }

      script.src = url;
      document.getElementsByTagName('head')[0].appendChild(scr);
    }

接下来,将该函数导入您要使用的组件中:

import React from 'react';
import loadScript from 'helpers/load-script';

class testComponent extends React.Component {
    
  componentDidMount() {
    loadScript('https://apis.google.com/js/client.js', () => {
    // do mail api stuff here               
    });
  }
   
  render() {
    return (
      <div>hi there</div>
    );
  }
}

export default testComponent;

【讨论】:

  • 你能给我一个更全面的例子吗?我已将您的代码示例粘贴到我的Mail.js 中,我继续收到gapi undefined
  • 我希望你替换了 'your-external-file.js' 的东西 :D 我现在正在编辑答案。
【解决方案2】:

我在使用 GrowSurf Javascript Web API 时遇到了同样的问题,在渲染函数之后加载了外部脚本,并且它的函数在 componentDidMount() 中未定义。 这是我用来使 GrowSurf 函数不被未定义的逻辑。它还可以帮助任何想要使用 index.html 中引入的任何外部 JS 的功能的人。

您可以在componentDidMount()中使用DOMSubtreeModified检查每次修改DOM时,一旦加载(找到)外部JS在那里运行您的函数,然后停止DOMSubtreeModified的循环。

componentDidMount() {
    let functionDefined = false;
    window.addEventListener('DOMSubtreeModified', function () {
        if(!functionDefined) {
            if (window.growsurf) {
                console.log('a function is defined', window.growsurf.getReferrerId());
                functionDefined = true;
            }
        }   
    }, false);
}

对于您的情况,您可以简单地执行此操作。

componentDidMount() {
    let functionDefined = false;
    window.addEventListener('DOMSubtreeModified', function () {
        if(!functionDefined) {
            if (window.gapi) {
                // do mail api stuff here       
                functionDefined = true;
            }
        }   
    }, false);
}

【讨论】:

    猜你喜欢
    • 2017-09-30
    • 2016-11-08
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 2017-12-28
    相关资源
    最近更新 更多