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

登录后history.push()无法跳转问题求助

解决React Router中登录后history.push()不触发页面跳转的问题

我看了你的代码,问题核心在于App组件的认证状态没有在登录操作后及时更新,导致路由跳转逻辑没有触发。

问题根源

App里的useEffect依赖的是空数组[],这意味着它只会在组件首次挂载时执行一次。当你在Login组件里设置了authorization cookie并调用history.push('/')后,App组件的isAuthenticated状态还是初始的false——首页的Route依然会渲染Login组件,而不是触发Redirect到/home。只有手动刷新页面,App重新挂载时,useEffect才会再次检查cookie、更新状态,这时候才会完成跳转。

解决方案

我们需要让App组件能实时感知到认证状态的变化,这里提供几种可行方案,按推荐程度排序:

方案1:用Context管理全局认证状态(最推荐)

把认证状态和更新方法抽离到全局Context中,让Login组件可以直接触发状态更新,不用依赖cookie的被动读取。

  1. 先创建AuthContext文件:
// AuthContext.js
import React, { createContext, useContext, useState, useEffect } from 'react';
import cookie from 'cookie';

const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [isAuthenticated, setAuthenticated] = useState(false);

  // 初始化检查cookie
  useEffect(() => {
    checkAuthStatus();
  }, []);

  // 抽离检查认证状态的方法
  const checkAuthStatus = () => {
    setAuthenticated(!!cookie.get('authorization'));
  };

  // 登录成功后调用的方法
  const handleLoginSuccess = () => {
    setAuthenticated(true);
  };

  // 登出方法(可选)
  const handleLogout = () => {
    cookie.remove('authorization', { path: '/' });
    setAuthenticated(false);
  };

  return (
    <AuthContext.Provider value={{ isAuthenticated, handleLoginSuccess, handleLogout }}>
      {children}
    </AuthContext.Provider>
  );
};

export const useAuth = () => useContext(AuthContext);
  1. 修改App组件,使用Context中的状态:
// App.js
import { AuthProvider, useAuth } from './AuthContext';
import { Router, Switch, Route, Redirect } from 'react-router-dom';

function AppContent() {
  const { isAuthenticated } = useAuth();

  return (
    <Switch>
      <Route exact path="/">
        {isAuthenticated ? <Redirect to="/home" /> : <Login />}
      </Route>
      <PrivateRoute exact path="/user/:id" component={UserDetail} auth={isAuthenticated} />
      <PrivateRoute exact path="/createuser" component={CreateUser} auth={isAuthenticated} />
      <PrivateRoute exact path="/home" component={ListUser} auth={isAuthenticated} />
    </Switch>
  );
}

function App() {
  return (
    <AuthProvider>
      <Router>
        <AppContent />
      </Router>
    </AuthProvider>
  );
}

export default App;
  1. 修改Login组件,登录成功后更新全局状态:
// login.js
import { useAuth } from './AuthContext';
import { useHistory } from 'react-router-dom';

function Login() {
  const history = useHistory();
  const { handleLoginSuccess } = useAuth();

  const loginUser = (body) => {
    SetLoader(true);
    fetch('/api/v2/users/tokens', {
      method: 'POST',
      body: JSON.stringify(body),
      headers: {
        'Content-Type': 'application/json',
      }
    })
    .then(response => {
      SetLoader(false);
      if (response.status == 200) {
        SetError(false);
        cookie.set('authorization', response.headers.map.authorization, { path: '/' });
        // 先更新全局认证状态
        handleLoginSuccess();
        // 再跳转(直接跳/home或/都可以,状态更新后路由逻辑会生效)
        history.push('/home');
      } else {
        SetError(true);
        StoreResponse(JSON.parse(response._bodyInit).message);
      }
    })
    .catch((error) => {
      console.error('Error:', error);
    });
  }

  // 其余组件代码...
}

export default Login;

方案2:简化版 - 登录后直接跳转到/home

如果不想引入Context,也可以直接在登录成功后跳转到目标页面,绕过首页的Redirect逻辑:

// login.js 中的修改
if (response.status == 200) {
  SetError(false);
  cookie.set('authorization', response.headers.map.authorization, { path: '/' });
  // 直接跳转到/home,跳过首页的判断
  history.push('/home');
}

这个方案能快速解决跳转问题,但没有同步全局状态,后续如果有其他依赖isAuthenticated的逻辑可能会出现不一致,适合临时快速修复。

方案3:用react-cookie监听cookie变化(可选)

可以借助react-cookie库的useCookie钩子自动监听cookie变化,触发状态更新:

// App.js
import { useCookie } from 'react-cookie';

function App() {
  const [authCookie] = useCookie('authorization');
  const [isAuthenticated, setAuthenticated] = useState(false);

  // 当authCookie变化时自动更新状态
  useEffect(() => {
    setAuthenticated(!!authCookie);
  }, [authCookie]);

  // 其余组件代码...
}

这个方法不需要修改Login组件,但需要额外安装依赖,灵活性不如Context方案。

总结

核心问题就是认证状态没有在登录操作后同步更新,只要让App组件能及时感知到登录成功的事件,更新isAuthenticated状态,history.push()就能正常触发路由跳转逻辑了。

内容的提问来源于stack exchange,提问作者Sriharsha K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:36:54