在React-Router v4中以编程方式导航

时间:2016-10-06 11:16:27

标签: reactjs react-router

我等不及了,我开始使用react-router v4的最新alpha版本。全新<BrowserRouter/>非常适合保持您的用户界面与浏览器历史记录同步,但如何使用它以编程方式进行导航?

9 个答案:

答案 0 :(得分:36)

路由器将在history哈希中向您的组件添加props对象。因此,在您的组件中,只需执行以下操作:

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

以下是一个完整的例子:

App.js

import React from 'react'
import {BrowserRouter as Router, Route} from 'react-router-dom'

import Login from './Login'

export default class App extends React.Component {
  render() {
    return (
      <Router>
        <div>
          <Route exact path='/login' component={Login} />
        </div>
      </Router>
    )
  }
}

Login.js

import React, {PropTypes} from 'react'

export default class Login extends React.Component {
  constructor(props) {
    super(props)
    this.handleLogin = this.handleLogin.bind(this)
  }

  handleLogin(event) {
    event.preventDefault()
    // do some login logic here, and if successful:
    this.props.history.push(`/mypath`)
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleLogin}>
          <input type='submit' value='Login' />
        </form>
      </div>
    )
  }
}

答案 1 :(得分:19)

过去,您可能已使用browserHistory来推送新路径。这不适用于react-router v4。相反,您已经使用了React的contextrouter的{​​{1}}方法。

这是一个简单的例子:

transitionTo

import React from 'react'; class NavigateNext extends React.Component { constructor() { super(); this.navigateProgramatically = this.navigateProgramatically.bind(this); } navigateProgramatically(e) { e.preventDefault(); this.context.router.transitionTo(e.target.href) } render() { return ( <Link to={"/next-page"} onClick={this.navigateProgramatically} >Continue</Link> ); } } NavigateNext.contextTypes = { router: React.PropTypes.object }; 只是可用的transitionTo方法之一。 router对象还包含值得查看的routerblockTransitions(getPromptMessage)createHref(to)

这是official react-router tutorial提到的上述方法。 如果您想了解有关使用replaceWith(loc)的{​​{1}}的更多信息,请查看docs

答案 2 :(得分:13)

我没有足够的声誉来评论,但在回答@ singularity的问题时,您必须在组件类中包含您希望提供的上下文属性。 contextTypes静态属性。

来自the React docs on context

  

如果未定义contextTypes,则上下文将是一个空对象。

在这种情况下:

class NavigateNext extends React.Component {

  // ...

  static contextTypes = {
    router: PropTypes.object
  }

  // ...

}

propTypes不同,contextTypes实际上会导致React的行为不同,而且不仅仅是用于类型检查。

答案 3 :(得分:9)

使用withRouter会将路由器属性添加到您的组件,然后您可以访问history并像使用v3一样使用push

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

class Form extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      input: '',
    };

    this._submit = this._submit.bind(this);
  }

  render() {
    return (
      <form onSubmit={this._submit}>
        <input type="text" onChange={(event) => this.setState({input: event.target.value})}/>

        <button type="submit">Submit</button>
      </form>
    );
  }

  _submit(event) {
    event.preventDefault();

    this.props.history.push(`/theUrlYouWantToGoTo`);
  }
}

export default withRouter(Form);

答案 4 :(得分:6)

react-router v4 beta发布,API稍有改变。如果您使用的是最新版本,请this.context.router.transitionTo(e.target.href)代替this.context.router.push(e.target.href)

链接到新文档:https://reacttraining.com/react-router/#context.router

答案 5 :(得分:5)

如果您需要访问组件之外的历史记录(例如在redux 操作中),react-router已发布其原始解决方案here

基本上,您必须创建自己的历史记录对象:

import { createBrowserHistory } from 'history';

const history = createBrowserHistory();

并将其传递给您的路由器:

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

ReactDOM.render((
  <Router history={history}> // <<-- the history object
    <App/>
  </Router>
), document.getElementById('root'))

注意:你必须在这里使用普通路由器而不是BrowserRouter或HashRouter!

如果您现在导出history,则可以在任何地方使用它:

import history from './history';

history.push('/home');

答案 6 :(得分:1)

我发现使用状态,三元运算符和<Redirect>效果最好。我认为这也是首选方式,因为它最接近v4的设置方式。

在构造函数()

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

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

答案 7 :(得分:1)

使用withRouter

import React, { PropTypes } from 'react'
import { withRouter } from 'react-router'

// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
  static propTypes = {
    match: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  }

  render() {
    const { match, location, history } = this.props

    return (
      <div>You are now at {location.pathname}</div>
    )
  }
}

// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation)

答案 8 :(得分:0)

使用react-router确实很困难。没有一个选项是直接的。 this.props.history给了我undefined。但是

window.location='/mypath/';

version 5.0.0中为我工作。不知道这是否是正确的方法。