React router v4使用声明性重定向而不渲染当前组件

时间:2017-06-06 13:24:51

标签: javascript reactjs react-router-v4

我使用类似的代码this在用户登录后在我的应用中重定向。代码如下所示:

import React, { Component } from 'react'
import { Redirect } from 'react-router'

export default class LoginForm extends Component {
  constructor () {
    super();
    this.state = {
      fireRedirect: false
    }
  }

  submitForm = (e) => {
    e.preventDefault()
    //if login success
    this.setState({ fireRedirect: true })
  }

  render () {
    const { from } = this.props.location.state || '/'
    const { fireRedirect } = this.state

    return (
      <div>
        <form onSubmit={this.submitForm}>
          <button type="submit">Submit</button>
        </form>
        {fireRedirect && (
          <Redirect to={from || '/home'}/>
        )}
      </div>
    )

  }
}

触发成功登录后正常工作。但有一种情况是,登录用户进入登录页面并应自动重定向到&#34; home&#34;页面(或任何其他页面)。

如何在不渲染当前组件的情况下使用重定向组件(根据我的理解discouraged)强制推送到历史记录(例如在componentWillMount中)?

2 个答案:

答案 0 :(得分:9)

解决方案1 ​​

您可以使用withRouter HOC通过道具访问历史记录。

导入withRouter。

import {
  withRouter
} from 'react-router-dom';

然后用HOC包裹。

// Example code
export default withRouter(connect(...))(Component)

现在您可以访问this.props.history。与componentWillMount()一起使用。

componentWillMount() {
  const { history } = this.props;

  if (this.props.authenticated) {
    history.push('/private-route');
  }
}

解决方案2 好多了

以下是reacttraining上的示例。

哪种方式对您有用。

但您只需要创建LoginRoute来处理您描述的问题。

const LoginRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest} render={props => (
    fakeAuth.isAuthenticated ? (
        <Redirect to={{
          pathname: '/private-route',
          state: { from: props.location }
        }} />
      ) : (
        <Component {...props} />
      )
  )} />
);

<Router />内部只需替换

<Route path="/login" component={Login}/>

<LoginRoute path="/login" component={Login}/>

现在,每当有人尝试以经过身份验证的用户身份访问/login路由时,他都会被重定向到/private-route。这是更好的解决方案,因为如果不满足条件,它就不会安装LoginComponent

答案 1 :(得分:0)

这是另一个解决方案,完全不涉及React内容。例如。如果您需要在redux-saga中导航。

拥有文件 history.js

import {createBrowserHistory} from 'history';
export default createBrowserHistory();

在定义路由的地方,请勿使用浏览器路由器,而应使用常规的<Router/>

import history from 'utils/history';

...

<Router history={history}>
  <Route path="/" component={App}/>
</Router>

就是这样。现在,您可以使用相同的历史记录导入并推送新路线。

应用的任何部分

import history from 'utils/history';
history.push('/foo');

传奇中:

import {call} from 'redux-saga/effects';
import history from 'utils/history';

 ... 

history.push('/foo');
yield call(history.push, '/foo');