首次加载React谷歌登录组件出现google未定义错误求助
解决React组件中Google登录首次加载
google is undefined的问题 你遇到的核心问题是Google登录脚本还未加载完成,React组件就已经执行了初始化代码。首次加载(尤其是清除缓存后)脚本还没完成下载解析,window.google自然不存在;刷新时浏览器缓存了脚本,所以能正常获取到。
以下是两种可行的解决方案:
方案1:动态加载Google登录脚本并监听加载完成
通过动态插入脚本的方式,确保脚本加载完成后再执行Google登录初始化逻辑,从根源避免google未定义的问题。
修改后的组件代码:
import { useEffect } from "react"; import jwtDecode from "jwt-decode"; import { useDispatch } from "react-redux"; import { login } from "../redux/user"; import { setCurrentPath } from "../redux/currentpath"; const Login = () => { const dispatch = useDispatch(); function handleCallbackResponse(response) { const user = jwtDecode(response.credential); dispatch(login({ name: user.name, avatar: user.picture })); }; useEffect(() => { dispatch(setCurrentPath(window.location.pathname)); }, [dispatch]); useEffect(() => { let scriptLoaded = false; // 初始化Google登录逻辑 const initGoogleLogin = () => { window.google.accounts.id.initialize({ client_id: '650598283556-4tl875cetd7ueallsq486darhpj5e30n.apps.googleusercontent.com', callback: handleCallbackResponse }); window.google.accounts.id.renderButton( document.getElementById('signInDiv'), { theme: 'outline', size: 'large' } ); }; // 检查Google脚本是否加载完成 const checkGoogleScript = () => { if (window.google && !scriptLoaded) { scriptLoaded = true; initGoogleLogin(); } }; // 动态插入Google登录脚本 if (!window.google) { const script = document.createElement('script'); script.src = 'https://accounts.google.com/gsi/client'; script.async = true; script.defer = true; script.onload = checkGoogleScript; script.onerror = () => console.error('Google登录脚本加载失败'); document.body.appendChild(script); } else { initGoogleLogin(); } // 组件卸载时清理资源,避免重复渲染 return () => { if (window.google) { window.google.accounts.id.cancel(); } }; }, []); return ( <div className="content login"> <div className='greeting-text'> <h1>Welcome to <br className="br" /> Cat Room!</h1> <p>Here you can talk about some very interesting topics, like milk, yarn balls, mice and many more. So don't be shy, come and join us! You can log in with Google right below this pharagraph.</p> </div> <div id="signInDiv"></div> </div> ); }; export default Login;
关键改进点:
- 动态加载官方CDN的Google登录脚本,确保脚本加载完成后再执行初始化
- 增加脚本加载失败的错误提示
- 组件卸载时调用
google.accounts.id.cancel()清理资源,避免内存泄漏或重复渲染 - 规范
useEffect依赖项,符合React Hooks规则
方案2:条件判断+延迟重试(快速临时修复)
如果不想修改脚本加载方式,可以通过延迟重试的方式,等待google对象存在后再执行初始化:
// 替换原有的Google初始化useEffect useEffect(() => { const initGoogleLogin = () => { if (!window.google) { // 每100ms重试一次,直到google对象可用 setTimeout(initGoogleLogin, 100); return; } window.google.accounts.id.initialize({ client_id: '650598283556-4tl875cetd7ueallsq486darhpj5e30n.apps.googleusercontent.com', callback: handleCallbackResponse }); window.google.accounts.id.renderButton( document.getElementById('signInDiv'), { theme: 'outline', size: 'large' } ); }; initGoogleLogin(); // 组件卸载清理 return () => { if (window.google) { window.google.accounts.id.cancel(); } }; }, []);
关于GitHub Pages的n is undefined问题
该问题通常是脚本加载路径或初始化时机冲突导致的,方案1的动态加载方式直接从官方CDN拉取脚本,不受项目basename影响,能解决此问题。
内容的提问来源于stack exchange,提问作者jr-kick
相关产品推荐
相关产品推荐

