为何‘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
相关产品推荐
相关产品推荐

