我刚刚把react-router从v3替换为v4。 但我不确定如何以编程方式在组件的成员函数中导航。 即在handleClick()函数中,我想在处理一些数据后导航到/path/some/where。 我以前是这样做的:

import { browserHistory } from 'react-router'
browserHistory.push('/path/some/where')

但是我在v4中找不到这样的界面。 如何使用v4导航?


当前回答

我为此纠结了一段时间——如此简单,却又如此复杂,因为ReactJS只是一种完全不同的web应用程序编写方式,这对我们这些老年人来说非常陌生!

我创建了一个单独的组件来抽象混乱:

// LinkButton.js

import React from "react";
import PropTypes from "prop-types";
import {Route} from 'react-router-dom';

export default class LinkButton extends React.Component {

    render() {
        return (
            <Route render={({history}) => (
                <button {...this.props}
                       onClick={() => {
                           history.push(this.props.to)
                       }}>
                    {this.props.children}
                </button>
            )}/>
        );
    }
}

LinkButton.propTypes = {
    to: PropTypes.string.isRequired
};

然后将它添加到render()方法中:

<LinkButton className="btn btn-primary" to="/location">
    Button Text
</LinkButton>

其他回答

TL; diana:

if (navigate) {
  return <Redirect to="/" push={true} />
}

简单和声明性的答案是,您需要结合setState()使用<Redirect to={URL} push={boolean} />

Push:布尔值——当为true时,重定向将把一个新条目推到历史记录中,而不是替换当前的条目。


import { Redirect } from 'react-router'

class FooBar extends React.Component {
  state = {
    navigate: false
  }

  render() {
    const { navigate } = this.state

    // here is the important part
    if (navigate) {
      return <Redirect to="/" push={true} />
    }
   // ^^^^^^^^^^^^^^^^^^^^^^^

    return (
      <div>
        <button onClick={() => this.setState({ navigate: true })}>
          Home
        </button>
      </div>
    )
  }
}

完整的例子。 点击这里阅读更多。

本例使用ES7+属性初始化器初始化状态。如果你感兴趣的话,也看看这里。

我已经测试v4好几天了。到目前为止,我很喜欢它!过一段时间就明白了。

我也有同样的问题,我发现用下面的方法处理它是最好的(甚至可能是它的目的)。它使用state、三元操作符和<Redirect>。

在构造函数()中

this.state = {
    redirectTo: null
} 
this.clickhandler = this.clickhandler.bind(this);

在render()中

render(){
    return (
        <div>
        { this.state.redirectTo ?
            <Redirect to={{ pathname: this.state.redirectTo }} /> : 
            (
             <div>
               ..
             <button onClick={ this.clickhandler } />
              ..
             </div>
             )
         }

在clickhandler()中

 this.setState({ redirectTo: '/path/some/where' });

希望能有所帮助。让我知道。

第一步:只需要在上面导入一个东西:

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

第二步:在Route中,传递历史记录:

<Route
  exact
  path='/posts/add'
  render={({history}) => (
    <PostAdd history={history} />
  )}
/>

第三步:历史被接受为下一个组件的道具的一部分,所以你可以简单地:

this.props.history.push('/');

这很简单,也很有力。

因为有时我更喜欢通过应用程序切换路由,然后通过按钮,这是一个最小的工作示例,对我有用:

import { Component } from 'react'
import { BrowserRouter as Router, Link } from 'react-router-dom'

class App extends Component {
  constructor(props) {
    super(props)

    /** @type BrowserRouter */
    this.router = undefined
  }

  async handleSignFormSubmit() {
    await magic()
    this.router.history.push('/')
  }

  render() {
    return (
      <Router ref={ el => this.router = el }>
        <Link to="/signin">Sign in</Link>
        <Route path="/signin" exact={true} render={() => (
          <SignPage onFormSubmit={ this.handleSignFormSubmit } />
        )} />
      </Router>
    )
  }
}

如果使用函数组件,请使用useHistory钩子

你可以使用useHistory钩子获取历史实例。

import { useHistory } from "react-router-dom";

const MyComponent = () => {
  const history = useHistory();
  
  return (
    <button onClick={() => history.push("/about")}>
      Click me
    </button>
  );
}

useHistory钩子使您可以访问用于导航的历史实例。

在页面组件中使用history属性

React Router向页面组件注入一些属性,包括历史记录。

class HomePage extends React.Component {
  render() {
    const { history } = this.props;

    return (
      <div>
        <button onClick={() => history.push("/projects")}>
          Projects
        </button>
      </div>
    );
  }
}

用throuter包装子组件以注入路由器属性

withRouter包装器将路由器属性注入组件。例如,您可以使用此包装器注入路由器注销按钮组件放置在用户菜单。

import { withRouter } from "react-router";

const LogoutButton = withRouter(({ history }) => {
  return (
    <button onClick={() => history.push("/login")}>
      Logout
    </button>
  );
});

export default LogoutButton;