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

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

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

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


当前回答

对于React路由器v4+

假设在初始渲染过程中不需要导航(可以使用<Redirect>组件),这就是我们在应用程序中所做的。

定义返回null的空路由。这将允许您访问历史对象。您需要在定义路由器的顶层执行此操作。

现在,您可以在历史上做所有可以做的事情,如history.push()、history.replace()、history.go(-1)等。!

import React from 'react';
import { HashRouter, Route } from 'react-router-dom';

let routeHistory = null;

export function navigateTo(path) {
  if(routeHistory !== null) {
    routeHistory.push(path);
  }
}

export default function App(props) {
  return (
    <HashRouter hashType="noslash">
      <Route
        render={({ history }) => {
          routeHistory = history;
          return null;
        }}
      />
      {/* Rest of the App */}
    </HashRouter>
  );
}

其他回答

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,而不是实际导航到页面。

要将withRouter与基于类的组件一起使用,请尝试以下操作。不要忘记将导出语句更改为与Router一起使用:

从“react router dom”导入{withRouter}

class YourClass extends React.Component {
  yourFunction = () => {
    doSomeAsyncAction(() =>
      this.props.history.push('/other_location')
    )
  }

  render() {
    return (
      <div>
        <Form onSubmit={ this.yourFunction } />
      </div>
    )
  }
}

export default withRouter(YourClass);

警告:此答案仅涵盖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

要以编程方式进行导航,您需要将新的历史推送到组件中的props.history,这样就可以完成以下工作:

//using ES6
import React from 'react';

class App extends React.Component {

  constructor(props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick(e) {
    e.preventDefault()
    /* Look at here, you can add it here */
    this.props.history.push('/redirected');
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick}>
          Redirect!!!
        </button>
      </div>
    )
  }
}

export default App;

以下是最简单、最干净的方法,大约是当前的React Router 3.0.0和ES6:

使用ES6反应路由器3.x.x:

import { withRouter } from 'react-router';

class Example extends React.Component {
   // use `this.props.router.push('/some/path')` here
};

// Export the decorated class
export default withRouter(Example);

或者,如果不是默认类,则导出如下:

withRouter(Example);
export { Example };

注意,在3.x.x中,<Link>组件本身使用router.push,因此您可以传递任何传递<Linkto=标记的内容,例如:

   this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'