React集成Google OAuth API时回调函数未执行的问题
Google OAuth回调函数未执行问题排查
问题描述
我正在使用Google OAuth API在React中实现登录认证功能,目前可以登录已授权的Google用户,但代码中的handleCallbackResponse回调函数始终未执行。相关代码如下:
App.js
import './App.css'; import { useState, useEffect } from 'react'; import { GoogleOAuthProvider } from '@react-oauth/google'; import LoginBtn from './components/atoms/LoginBtn'; import jwt_decode from 'jwt-decode'; function App() { const [ user, setUser ] = useState({}) //Store my user data function handleCallbackResponse(response){ var userData = jwt_decode(response.credentials); console.log(userData); setUser(userData); } useEffect(() => { /*global google*/ google.accounts.id.initialize({ client_id: "Google Cliente goes here", callback: handleCallbackResponse }); }, []); //useEffect will run only if anything inside the empty array return ( <GoogleOAuthProvider clientId="My Google client goes here"> <div className="App"> <LoginBtn /> </div> </GoogleOAuthProvider> ); } export default App;
未执行的回调函数:
function handleCallbackResponse(response){ var userData = jwt_decode(response.credentials); console.log(userData); setUser(userData); }
初始化代码块:
useEffect(() => { /*global google*/ google.accounts.id.initialize({ client_id: "Google Cliente goes here", callback: handleCallbackResponse }); }, []);
已在index.html的head标签中添加脚本:
<script src="https://accounts.google.com/gsi/client" async defer></script>
排查原因及解决方案
混用两种集成方式导致冲突
你同时使用了@react-oauth/google的GoogleOAuthProvider组件和原生google.accounts.id.initialize方法,这两种方式属于不同的集成方案,会互相干扰,导致回调无法正确触发。
解决:删除手动的useEffect初始化逻辑,完全基于@react-oauth/google组件实现认证流程。回调函数绑定时机或引用问题
若坚持使用原生API,useEffect空依赖数组可能导致handleCallbackResponse函数引用过时,或者google对象未加载完成就执行了初始化。
解决:- 确保
google对象加载完成后再执行初始化,可通过监听脚本加载事件判断; - 将
handleCallbackResponse加入useEffect依赖数组,或用useCallback包裹函数避免引用变化:const handleCallbackResponse = useCallback((response) => { const userData = jwt_decode(response.credentials); console.log(userData); setUser(userData); }, []); useEffect(() => { if (window.google) { google.accounts.id.initialize({ client_id: "你的Google客户端ID", callback: handleCallbackResponse }); } }, [handleCallbackResponse]);
- 确保
客户端ID不一致
代码中google.accounts.id.initialize和GoogleOAuthProvider的客户端ID填写位置内容不一致,若实际配置的ID不同,会导致认证流程异常。
解决:确保两处的客户端ID完全一致,且为Google Cloud控制台中正确配置的ID。LoginBtn组件实现错误
若LoginBtn组件未正确渲染Google登录按钮,或未绑定正确的回调逻辑,也会导致回调不执行。
解决:- 若使用
@react-oauth/google,改用组件库提供的GoogleLogin组件:
同时修改App.js,传递回调:// LoginBtn.js import { GoogleLogin } from '@react-oauth/google'; import jwt_decode from 'jwt-decode'; function LoginBtn({ onUserLogin }) { return ( <GoogleLogin onSuccess={(credentialResponse) => { const userData = jwt_decode(credentialResponse.credential); onUserLogin(userData); }} onError={() => console.log('登录失败')} /> ); } export default LoginBtn;// App.js中 <GoogleOAuthProvider clientId="你的Google客户端ID"> <div className="App"> <LoginBtn onUserLogin={setUser} /> </div> </GoogleOAuthProvider> - 若使用原生API,在LoginBtn中调用渲染方法:
// LoginBtn.js import { useEffect, useRef } from 'react'; function LoginBtn() { const btnRef = useRef(null); useEffect(() => { if (window.google && btnRef.current) { google.accounts.id.renderButton( btnRef.current, { theme: 'outline', size: 'large' } // 配置按钮样式 ); } }, []); return <div ref={btnRef}></div>; } export default LoginBtn;
- 若使用
内容的提问来源于stack exchange,提问作者mateo ghidini
相关产品推荐
相关产品推荐

