【问题标题】:React router v4 use declarative Redirect without rendering the current componentReact router v4 使用声明式重定向而不渲染当前组件
【发布时间】:2017-11-07 13:04:04
【问题描述】:

用户登录后,我正在使用类似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>
    )

  }
}

触发成功登录后工作正常。但是有这样的情况,登录用户进入登录页面,应该会自动重定向到“主页”页面(或任何其他页面)。

如何在不渲染当前组件的情况下使用 Redirect 组件并且无需(据我了解 discouraged)强制推送到历史记录(例如在 componentWillMount 中)?

【问题讨论】:

  • 您使用了错误的方法。重定向不应在组件内部单独使用。相反,您必须将组件与重定向一起放入Route。请参阅the official docs 中的示例。
  • 谢谢,是的,我的方法在某种程度上是错误的。我现在在我的路由器中定义了所有路由和重定向。

标签: javascript reactjs react-router-v4


【解决方案1】:

解决方案 1

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

使用路由器导入。

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

然后用 HOC 包装。

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

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

componentDidMount() {
  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} />
      )
  )} />
);

&lt;Router /&gt; 里面替换

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

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

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

【讨论】:

  • 解决方案 2 似乎是我正在寻找的!现在检查一下。
  • 它确实有效,我在我的项目中使用这种方法。如果您需要帮助,请告诉我。
  • 解决方案 2 完美运行,我可以摆脱组件中的路由逻辑。非常感谢!
  • 解决方案 1 存在一些合成器问题。导入是 react-router: import { withRouter } from "react-router"; 并且导出默认的 withRouter 括号应该这样覆盖:export default withRouter(connect(...)(Component))
【解决方案2】:

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

有文件history.js

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

在你定义路由的地方,不要使用浏览器路由器,而只是一般&lt;Router/&gt;

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');

【讨论】:

    猜你喜欢
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    • 2018-01-10
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多