You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何‘google’关键字未定义?React集成Google OAuth问题

解决Google OAuth中google未定义的问题

问题根源

你同时混用了**@react-oauth/google**封装库和原生GSI脚本的初始化逻辑,而且GSI脚本通过async defer加载,React组件挂载时全局google对象可能还未加载完成,导致报错。另外,@react-oauth/google已经封装了GSI核心功能,不需要手动调用原生的google.accounts.id.initialize。


推荐解决方案:纯使用@react-oauth/google库

该库已帮你处理客户端ID配置、全局对象加载等问题,代码更符合React组件化逻辑。

1. 修改App.js核心代码

import './App.css';
import { useState } from 'react';
import { GoogleOAuthProvider, GoogleLogin, googleLogout } from '@react-oauth/google';
import jwtDecode from 'jwt-decode';

function App() {
  const [user, setUser] = useState({});

  // 处理登录成功回调
  const handleLoginSuccess = (response) => {
    const userData = jwtDecode(response.credential);
    setUser(userData);
    console.log(userData);
  };

  // 处理登录失败
  const handleLoginFailure = (error) => {
    console.error('登录失败:', error);
  };

  // 处理退出登录
  const handleLogout = () => {
    googleLogout();
    setUser({});
  };

  return (
    <GoogleOAuthProvider clientId="你的客户端ID.apps.googleusercontent.com">
      <div className="App">
        {Object.keys(user).length === 0 ? (
          {/* 库内置的Google登录按钮 */}
          <GoogleLogin
            onSuccess={handleLoginSuccess}
            onError={handleLoginFailure}
          />
        ) : (
          <div>
            <p>欢迎, {user.name}</p>
            <button onClick={handleLogout}>退出登录</button>
          </div>
        )}
      </div>
    </GoogleOAuthProvider>
  );
}

export default App;

2. 自定义LoginBtn组件(可选)

如果需要自定义登录按钮样式,在LoginBtn.jsx中使用库提供的useGoogleLogin钩子:

// components/atoms/LoginBtn.jsx
import { useGoogleLogin } from '@react-oauth/google';
import jwtDecode from 'jwt-decode';

export default function LoginBtn({ onUserSet }) {
  const login = useGoogleLogin({
    onSuccess: (response) => {
      const userData = jwtDecode(response.credential);
      onUserSet(userData);
    },
    onError: (error) => console.error('登录失败:', error),
  });

  return <button onClick={() => login()}>自定义Google登录</button>;
}

随后在App.js中引入使用:

// App.js
import './App.css';
import { useState } from 'react';
import { GoogleOAuthProvider, googleLogout } from '@react-oauth/google';
import LoginBtn from './components/atoms/LoginBtn';

function App() {
  const [user, setUser] = useState({});

  const handleLogout = () => {
    googleLogout();
    setUser({});
  };

  return (
    <GoogleOAuthProvider clientId="你的客户端ID.apps.googleusercontent.com">
      <div className="App">
        {Object.keys(user).length === 0 ? (
          <LoginBtn onUserSet={setUser} />
        ) : (
          <div>
            <p>欢迎, {user.name}</p>
            <button onClick={handleLogout}>退出登录</button>
          </div>
        )}
      </div>
    </GoogleOAuthProvider>
  );
}

export default App;

备选方案:坚持使用原生GSI脚本(不推荐)

如果一定要用原生GSI脚本,需确保google对象加载完成后再初始化:

import './App.css';
import { useState, useEffect } from 'react';
import jwtDecode from 'jwt-decode';

function App() {
  const [user, setUser] = useState({});

  function handleCallbackResponse(response){
    const userData = jwtDecode(response.credential);
    setUser(userData);
    console.log(userData);
  }

  useEffect(()=>{
    const initGoogleAuth = () => {
      // 检查全局google对象是否存在
      if (window.google?.accounts?.id) {
        window.google.accounts.id.initialize({
          client_id: '你的客户端ID.apps.googleusercontent.com',
          callback: handleCallbackResponse
        });
        // 渲染登录按钮到指定容器
        window.google.accounts.id.renderButton(
          document.getElementById('google-login-container'),
          { theme: 'outline', size: 'large' }
        );
      } else {
        // 未加载完成则延迟重试
        setTimeout(initGoogleAuth, 100);
      }
    };

    initGoogleAuth();
  }, []);

  return (
    <div className="App">
      <div id="google-login-container"></div>
      {user.name && <p>欢迎, {user.name}</p>}
    </div>
  );
}

export default App;

注意:这种方式需要移除@react-oauth/google相关导入和GoogleOAuthProvider,避免冲突。


内容的提问来源于stack exchange,提问作者mateo ghidini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 20:24:22