加载 React 组件时未定义 gapi

Posted

技术标签:

【中文标题】加载 React 组件时未定义 gapi【英文标题】:gapi is not defined when loading React Component 【发布时间】:2017-09-30 18:28:50 【问题描述】:

我正在尝试使用 React 集成 Google 登录 (link)。 我发现一个问题过去解决了这个问题Using google sign in button with react 2

我复制了上述相同的步骤。在我的index.html 我愿意

<script src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded" async defer></script>
    <script type="text/javascript">
        function triggerGoogleLoaded() 
            console.log("google event loaded");
            window.dispatchEvent(new Event('google-loaded'));
        
    </script>

那么我的Component 看起来像

var LoginButton = React.createClass(

    onSignIn: function(googleUser) 
        console.log("user signed in"); // plus any other logic here
    ,

    renderGoogleLoginButton: function() 
        console.log('rendering google signin button');
        gapi.signin2.render('my-signin2', 
            'scope': 'https://www.googleapis.com/auth/plus.login',
            'width': 200,
            'height': 50,
            'longtitle': true,
            'theme': 'light',
            'onsuccess': this.onSignIn
        )
    ,

    componentDidMount: function() 
        window.addEventListener('google-loaded',this.renderGoogleLoginButton);
    ,

    render: function() 
        let displayText = "Sign in with Google";
        return (
            <div class="g-signin2" data-onsuccess="onSignIn"></div>
        );
    

);

export default LoginButton;

当我使用yarn start 运行程序时,我得到了

/Users/Harit.Himanshu/bl/sources/webs/google-login/src/LoginButton.js
  11:9   error    'gapi' is not defined                             no-undef
  26:13  warning  'displayText' is assigned a value but never used  no-unused-vars

✖ 2 problems (1 error, 1 warning)

完整的源代码可在https://github.com/hhimanshu/google-login-with-react获得

有人可以帮我理解我的错误吗?

谢谢

【问题讨论】:

【参考方案1】:

在我看来,您正在将 google apis 作为脚本标签加载,我们希望将 window.gapi 设置为 google api。但是,您随后正在运行 eslint 或其他一些检查器,并且不知道应该存在 window.gapi。它失败了,因为它看到你使用了一个未声明的变量。

一个便宜的解决办法是告诉 Eslint 你知道你在做什么;

/* global gapi */

把它放在文件的顶部,eslint 会将gapi 视为已知的全局变量。

【讨论】:

感谢@steve,这帮助我获得了按钮,现在我被***.com/questions/43767485/… 卡住了,你知道我在哪里犯错了吗?【参考方案2】:

这对我有用。放到componentDidMount或者构造函数中:

componentDidMount() 
    window.gapi.load('auth2', () => 
        // Retrieve the singleton for the GoogleAuth library and set up the client.
        this.auth2 = window.gapi.auth2.init(
            client_id: '436676563344-.apps.googleusercontent.com',
            cookiepolicy: 'single_host_origin',
        );

        this.auth2.attachClickHandler(this.refs.googleButton, ,
            (googleUser) => 
                this.googleLogin(googleUser.getBasicProfile());
            , (error) => 

            );
    );

【讨论】:

我仍然收到 OP 的错误 (Uncaught ReferenceError: gapi is not defined)。您是否在某个地方定义了 gapi? 你是否把 放在你的脚本之前? 你知道我怎样才能让 gapi 与 react-native 一起工作吗? @Bomber 抱歉,但我不知道 :(【参考方案3】:

你也可以试试gapi-script这个包,这个包即时提供gapi,所以你不用等待任何脚本加载,直接导入使用:

import  gapi  from 'gapi-script';

【讨论】:

不是一个好的解决方案,因为 gapi 脚本是由 Google 动态更新的,而这只是脚本的硬拷贝。您最终可能会得到一个过时的脚本版本,您的应用程序可能会停止工作。 是的,我同意你的观点,我不推荐这个包用于公司和企业项目,只推荐给小项目学习等。 包已更新,现在有一个功能可以从google的链接下载和使用真正的脚本。【参考方案4】:

确保您没有使用异步延迟,这将导致 window.gapi.someMethod() 和您的脚本加载之间的竞争条件

简而言之,从 index.html 中的脚本标记中删除 async defer

之前

<script src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded" async defer></script>

之后

<script src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded"></script>

【讨论】:

【参考方案5】:

我有一个类似的问题。

我使用 'react-snap' 进行 SEO。它阻止我使用“gapi”。我找到了 navigator.userAgent 'ReactSnap'。

if (navigator.userAgent !== 'ReactSnap') 
    // some code to dynamically load a script
    let myScript = document.createElement('script')
    myScript.setAttribute('src', 'https://apis.google.com/js/platform.js')
    document.body.appendChild(myScript)

我解决了一个问题。 效果很好。

【讨论】:

以上是关于加载 React 组件时未定义 gapi的主要内容,如果未能解决你的问题,请参考以下文章

运行 Jest 测试时未定义`regeneratorRuntime`

将道具传递给兄弟姐妹reactJS时未定义

AngularJS:使用ngRoute路由时未加载组件控制器

使用 React.lazy 时未捕获的未定义错误

React Hooks Form:提交时未定义的值

使用react Context(Ionic-React)时未定义history.push()[重复]