React登录函数中history.push首次点击不跳转问题
问题修复方案
核心问题分析
- 路由路径不匹配:LoginPage中登录成功后跳转的路径是
/dashboard,但实际路由配置里Dashboard的路径是/mobile/dashboard,第一次跳转时找不到对应路由,触发了默认重定向逻辑。 - Auth状态同步延迟:AWS Amplify的
Auth.signIn完成后,内部状态需要短暂时间同步,而PrivateRoute仅监听location变化触发状态检查,此时Auth状态尚未更新,导致判断用户未登录,重定向回登录页;第二次点击时状态已同步,因此跳转生效。
具体修复步骤
1. 修正LoginPage的跳转路径
修改LoginPage中login函数的跳转路径,确保与路由配置一致:
const login = async () => { try { const user = await Auth.signIn(email, password); console.log('Login successful:', user); history.push('/mobile/dashboard'); // 修正为完整路由路径 } catch (error) { console.error('Login failed:', error); } };
2. 优化PrivateRoute的状态监听逻辑
在PrivateRoute中添加Amplify Auth的状态监听,确保Auth状态变化时能实时更新登录状态判断:
const PrivateRoute = ({ component: Component, render, ...rest }) => { const [isLoggedIn, setIsLoggedIn] = useState(false); const [checkingStatus, setCheckingStatus] = useState(true); const [user, setUser] = useState(null); const location = useLocation(); useEffect(() => { // 监听Amplify Auth状态变化 const unsubscribeAuth = Auth.listen((authState) => { if (authState === 'signedIn') { checkAuthState(); } else if (authState === 'signedOut') { setIsLoggedIn(false); } }); // 初始化检查登录状态 checkAuthState(); // 清理监听 return () => { unsubscribeAuth(); }; }, [location]); async function checkAuthState() { setCheckingStatus(true); try { const currentUser = await Auth.currentAuthenticatedUser({ bypassCache: false }); // 启用缓存提升性能 setIsLoggedIn(true); setUser(currentUser); } catch (error) { console.error('Not logged in', error); setIsLoggedIn(false); } finally { setCheckingStatus(false); } } // 其余代码保持不变 };
3. 可选:确保IonRouterOutlet的路由上下文正确
确认HomePage中的IonRouterOutlet包裹了所有需要路由跳转的组件,Ionic React的路由需要依赖IonRouterOutlet提供的上下文,确保history.push能正确触发路由更新。
修复原理
- 修正路径后,第一次跳转就能匹配到正确的PrivateRoute;
- 添加Auth状态监听后,当
Auth.signIn完成并更新内部状态时,PrivateRoute会重新检查登录状态,确保跳转时能正确识别用户已登录,避免重定向回登录页。
内容的提问来源于stack exchange,提问作者Damiano Dotto
相关产品推荐
相关产品推荐

