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

react-router-dom是否含browserHistory?如何用history.push跳转页面

React Router DOM 实现页面跳转指南(针对你的代码)

嘿,我来帮你理清这些问题,一步步解决登录后跳转的需求:

核心问题解答

  • react-router-dom 里还有 browserHistory 吗?
    没有啦!从 react-router-dom v4 开始,browserHistory 就被移除了,不再直接对外暴露。现在我们是通过路由上下文传递的 history 对象来实现跳转,这个对象有 push 方法可以用。
  • react-router-dom 本身有 push 属性吗?
    不是库本身带,而是路由给组件传递的 props.history 对象拥有 push 方法,我们就是靠它来跳转页面的。

具体修改步骤

先确认你已经安装了 react-router-dom(不需要额外装 react-router,它已经包含在前者里了),如果没装,执行:

npm install react-router-dom
# 或者用 yarn
yarn add react-router-dom

1. 先修正 Routes.js 的 Router 类型

你当前用的 Router 需要换成 BrowserRouter(这是实现browser history模式的正确组件),修改后的代码:

// 导入正确的组件
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
// 记得替换成你实际的组件路径
import HomePage from './HomePage';
import About from './About';
import LoginForm from './LoginForm';
import Companies from './Companies';
import Services from './Services';
import Contact from './Contact';
import UserPage from './UserPage';

class Routes extends Component {
  render() {
    return (
      <div>
        <Router>
          <Switch>
            <Route exact path="/" component={HomePage}/>
            <Route path="/about" component={About}/>
            <Route path="/loginform" component={LoginForm}/>
            <Route path="/companies" component={Companies}/>
            <Route path="/services" component={Services}/>
            <Route path="/contact" component={Contact}/>
            <Route path="/userpage" component={UserPage}/>
          </Switch>
        </Router>
      </div>
    );
  }
}

export default Routes;

2. 方案一:在 LoginForm 中监听登录状态跳转(最直接)

因为你的登录状态存在Redux里,我们可以在LoginForm组件中监听isLoginSuccess的变化,一旦登录成功就触发跳转:

修改 LoginForm.js:

// 导入 withRouter 高阶组件,用来获取 history props
import { withRouter } from 'react-router-dom';

class LoginForm extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.onSubmit = this.onSubmit.bind(this);
  }

  // 监听props变化,当登录成功状态从false变true时跳转
  componentDidUpdate(prevProps) {
    if (!prevProps.isLoginSuccess && this.props.isLoginSuccess) {
      this.props.history.push('/userpage');
    }
  }

  render() {
    let {username, password} = this.state;
    let {isLoginPending, isLoginSuccess, loginError} = this.props;
    return (
      <div>
        <Back/>
        <header>
          <h1>Company Login</h1>
        </header>
        <form name="loginForm" onSubmit={this.onSubmit}>
          <div className="imgcontainer">
            <img src={avatar} alt={"Avatar"} className={"avatar"}/>
          </div>
          <div className="form-group-collection">
            <div className="form-group">
              <label>Username/User ID:</label>
              <input name="username" onChange={e => this.setState({username: e.target.value})} value={username}/>
            </div>
            <div className="form-group">
              <label>Password:</label>
              <input type="password" name="password" onChange={e => this.setState({password: e.target.value})} value={password}/>
            </div>
          </div>
          <br/>
          <input type="submit" value="Login" />
        </form>
        <footer>Copyright &copy; multihands.com. </footer>
      </div>
    )
  }

  onSubmit(e) {
    e.preventDefault();
    let { username, password } = this.state;
    this.props.login(username, password);
    this.setState({ username: '', password: '' });
  }
}

const mapStateToProps = (state) => {
  return {
    isLoginPending: state.isLoginPending,
    isLoginSuccess: state.isLoginSuccess,
    loginError: state.loginError
  };
}

const mapDispatchToProps = (dispatch) => {
  return {
    login: (username, password) => dispatch(login(username, password))
  };
}

// 用withRouter包裹connect后的组件,这样就能拿到history props
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(LoginForm));

3. 方案二:在Redux Action中直接跳转(适合逻辑集中管理)

如果你想把跳转逻辑和登录成功的逻辑放在一起,可以把history对象传到action里:

首先修改LoginForm的mapDispatchToProps:

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    login: (username, password) => dispatch(login(username, password, ownProps.history))
  };
}

然后修改Reducer.js里的login action和callLoginApi:

export function login(username, password, history) {
  return dispatch => {
    dispatch(setLoginPending(true));
    dispatch(setLoginSuccess(false));
    dispatch(setLoginError(null));

    callLoginApi(username, password, (error) => {
      dispatch(setLoginPending(false));
      if (!error) {
        dispatch(setLoginSuccess(true));
        // 登录成功后直接跳转
        history.push('/userpage');
      } else {
        dispatch(setLoginError(error));
      }
    });
  }
}

function callLoginApi(username, password, callback) {
  setTimeout(() => {
    if (username === logindetls.username && password === logindetls.password) {
      alert("Successfully Logged in...");
      callback(null); // 无错误时传null
    } else {
      alert('Invalid username and password');
      callback(new Error('Invalid credentials')); // 有错误时传Error对象
    }
  }, 1000);
}

小提醒

  • 如果你的组件不是直接被Route渲染的(比如嵌套在其他组件里),一定要用withRouter包裹才能拿到history props。
  • 要是以后改成函数组件,直接用useHistory钩子就行:const history = useHistory(); 然后调用history.push('/userpage')。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:22:59