使用react router,我可以使用Link元素来创建由react route本地处理的链接。

我看到它在内部调用this.context.transitionTo(…)。

我想做导航。不是来自链接,而是来自下拉选择(例如)。我如何在代码中执行此操作?this.context是什么?

我看到了导航混合,但我可以在没有混合的情况下这样做吗?


当前回答

React路由器v2

对于最新版本(v2.0.0-rc5),推荐的导航方法是直接推到历史单例。您可以在组件外部导航文档中看到这一点。

相关摘录:

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

如果使用更新的react router API,则需要在组件内部使用this.props中的历史记录,以便:

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

它还提供pushState,但对于每个记录的警告,它都是不推荐的。

如果使用react router redux,它提供了一个推送功能,您可以这样调度:

import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));

然而,这可能仅用于更改URL,而不是实际导航到页面。

其他回答

对于ES6+React组件,以下解决方案适用于我。

我跟随费利佩·斯金纳,但添加了一个端到端解决方案,以帮助像我这样的初学者。

以下是我使用的版本:

“反应路由器”:“^2.7.0”“反应”:“^15.3.1”

下面是我的react组件,其中我使用react路由器进行编程导航:

import React from 'react';

class loginComp extends React.Component {
   constructor( context) {
    super(context);
    this.state = {
      uname: '',
      pwd: ''
    };
  }

  redirectToMainPage(){
        this.context.router.replace('/home');
  }

  render(){
    return <div>
           // skipping html code 
             <button onClick={this.redirectToMainPage.bind(this)}>Redirect</button>
    </div>;
  }
};

 loginComp.contextTypes = {
    router: React.PropTypes.object.isRequired
 }

 module.exports = loginComp;

以下是路由器的配置:

 import { Router, Route, IndexRedirect, browserHistory } from 'react-router'

 render(<Router history={browserHistory}>
          <Route path='/' component={ParentComp}>
            <IndexRedirect to = "/login"/>
            <Route path='/login' component={LoginComp}/>
            <Route path='/home' component={HomeComp}/>
            <Route path='/repair' component={RepairJobComp} />
            <Route path='/service' component={ServiceJobComp} />
          </Route>
        </Router>, document.getElementById('root'));

警告:此答案仅涵盖1.0之前的ReactRouter版本之后,我将用1.0.0-rc1用例更新这个答案!

你也可以在没有混合的情况下这样做。

let Authentication = React.createClass({
  contextTypes: {
    router: React.PropTypes.func
  },
  handleClick(e) {
    e.preventDefault();
    this.context.router.transitionTo('/');
  },
  render(){
    return (<div onClick={this.handleClick}>Click me!</div>);
  }
});

有上下文的问题是,除非在类上定义contextType,否则它是不可访问的。

至于什么是上下文,它是一个对象,就像props一样,从父对象传递给子对象,但它是隐式传递的,不需要每次都重新声明props。看见https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html

在react router的上下文中,已经有大量的答案可以正确、准确地回答这个问题,但我想花点时间指出一些我在其他答案中没有提到的问题。

这是一种stackoverflow的比喻,建议用与原始问题不同的方式来做一些事情,但在这种情况下,由于问题的年龄,我觉得在当前的时间里,问题的表述会有所不同。

我建议放弃react router,只需通过window.location.href=[yoururlhere]推送到本地浏览器位置,然后通过正则表达式(或确切的)匹配window.location.pathname和您的预期路径来检查路径。

更简单的答案通常是最好的答案,在这种情况下,React Router的用例由本地位置对象API提供更好的服务。

React路由器v6

我已经有一段时间没有接触过React了,但我想感谢并强调Shimrit Snapir的以下评论:

在React Router 6.0上,<Redirect/>更改为<Navigator/>

React路由器V4

tl:dr;

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

简单而声明性的答案是,需要将<Redirectto={URL}push={boolean}/>与setState()结合使用

push:boolean-如果为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>
    )
  }
}

这里有一个完整的例子。在这里阅读更多信息。

PS.该示例使用ES7+属性初始化器初始化状态。如果你感兴趣的话,也可以看看这里。

也许不是最好的解决方案,但它可以完成任务:

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

// Create functional component Post
export default Post = () => (
    <div className="component post">

        <button className="button delete-post" onClick={() => {
            // ... delete post
            // then redirect, without page reload, by triggering a hidden Link
            document.querySelector('.trigger.go-home').click();
        }}>Delete Post</button>

        <Link to="/" className="trigger go-home hidden"></Link>

    </div>
);

基本上,与一个操作相关的逻辑(在本例中为删除后操作)最终将调用重定向触发器。这并不理想,因为您将在标记中添加DOM节点“触发器”,以便在需要时方便地调用它。此外,您将直接与DOM交互,这在React组件中可能是不需要的。

不过,这种类型的重定向并不经常需要。因此,在组件标记中添加一两个额外的隐藏链接并不会造成太大的伤害,特别是如果您为它们提供了有意义的名称。