React Router 4 - 难以以编程方式导航到新视图

React Router 4 - Difficulty with programmatically navigating to new view

使用 react 和 react-router 4 我试图在登录后将用户从登录视图发送到另一个视图。我已经看到了一些关于此的其他问题,但是 none解决方案,包括使用历史或上下文对我有用。

const {
  Redirect,
  HashRouter,
  Switch,
  Route,
  Link
} = ReactRouterDOM

const App = () =>  {

  const loginToServer = () => {
  // how do I redirect user to the home route?

  };

  return (
      <div className="App">
        <h2>Some App</h2>

        <HashRouter>
          <div>
            <Link to="/login" exact activeClassName="active">Login </Link><br/>
            <Link to="/home" activeClassName="active">Home </Link><br/>
            <hr/>
            <Switch>
              <Route path="/login"
                render={ () => <Login loginToServer = { loginToServer } /> }/>
              <Route path="/home" component={HomeComponent} />
              <Route exact path="/" render={() => (<Redirect to="/login"/>)}/>
            </Switch>
          </div>
        </HashRouter>
      </div>
    );
  };

const Login = (props) => {
  return (
    <div>
      <h4>Login Page</h4>
      <p>(pretend button is a submit button for a successful login)</p>
      <button onClick= { props.loginToServer }> login </button>
    </div>
  )}

const HomeComponent = () => <h4>Home page</h4>

ReactDOM.render(<App />, document.getElementById('root'));

以上代码在codepen中here。希望有人能告诉我实现这个的最简单方法。谢谢

首先,您要确保处理重定向的方法可以访问 history 对象,该对象作为 prop 传递给直接 Route 的任何组件d到.

查看您的代码,您应该将 loginToServer 函数移动到 Login 组件,因为,为什么要从其他任何地方调用它呢?

然后在您的 Login.js 文件中:

loginToServer() {
  ...handle actual login logic here...
  // if successful
  this.props.history.push('/home');
}

编辑:您必须将 Login 组件从功能组件转变为 class。

您必须使用路由器 history 对象来处理重定向。在您的情况下,组件 App 包含路由器,因此您必须使用 ref.

检索 history
const App = () =>  {

  let router;

  const loginToServer = () => {
    router.history.push('/home');
  };

  return (
    <div className="App">
      <h2>Some App</h2>

      <HashRouter ref={r => router = r}>
        {/* ... */}
      </HashRouter>
    </div>
  );
};

您也可以从 Login 组件进行重定向

<Route path="/login" component={Login}/>
//                              ^^^^^
//                   the router will be given as prop to Login 

const Login = ({ history }) => {
  return (
    // ...
      <button onClick={() => history.push('/home')}> login </button>
    // ...
  )
}

如果你想从子组件(不直接附加到路由)重定向,你可以使用 withRouter 高阶组件注入路由器。

const { withRouter } = ReactRouterDOM;

const SubComponent = withRouter(({ history }) => (
  <div onClick={() => history.push('/somewhere')} />
));