React-router:如何手动调用链接?

我是ReactJS和React-Router的新手。 我有一个组件,通过道具接收来自react-router<Link/>对象。 每当用户点击这个组件内的“下一个”button,我想手动调用<Link/>对象。

现在,我使用ref来访问后台实例,并手动点击<Link/>生成的“a”标签。

问题:有没有办法手动调用链接(例如this.props.next.go )?

这是我现在的代码:

 //in MasterPage.js var sampleLink = <Link to="/sample">Go To Sample</Link> <Document next={sampleLink} /> //in Document.js ... var Document = React.createClass({ _onClickNext: function() { var next = this.refs.next.getDOMNode(); next.querySelectorAll('a').item(0).click(); //this sounds like hack to me }, render: function() { return ( ... <div ref="next">{this.props.next} <img src="rightArrow.png" onClick={this._onClickNext}/></div> ... ); } }); ... 

这是我想要的代码:

 //in MasterPage.js var sampleLink = <Link to="/sample">Go To Sample</Link> <Document next={sampleLink} /> //in Document.js ... var Document = React.createClass({ render: function() { return ( ... <div onClick={this.props.next.go}>{this.props.next.label} <img src="rightArrow.png" /> </div> ... ); } }); ... 

React路由器v4 – redirect组件(更新2017/04/15)

v4推荐的方法是让你的渲染方法来捕捉redirect。 使用状态或道具来确定是否需要显示redirect组件(然后触发redirect)。

 import { Redirect } from 'react-router'; // ... your class implementation handleOnClick = () => { // some action... // then redirect this.setState({redirect: true}); } render() { if (this.state.redirect) { return <Redirect push to="/sample" />; } return <button onClick={this.handleOnClick} type="button">Button</button>; } 

参考: https : //reacttraining.com/react-router/web/api/Redirect

React路由器v4 – 参考路由器上下文

您还可以利用暴露给React组件的Router的上下文。

 static contextTypes = { router: PropTypes.shape({ history: PropTypes.shape({ push: PropTypes.func.isRequired, replace: PropTypes.func.isRequired }).isRequired, staticContext: PropTypes.object }).isRequired }; handleOnClick = () => { this.context.router.push('/sample'); } 

这是<Redirect />如何工作的。

参考: https : //github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Redirect.js#L46,L60

React Router v4 – 外部变更历史logging对象

如果你仍然需要做一些类似于v2的实现,你可以创build一个BrowserRouter的副本,然后将history公开为一个可导出的常量。 下面是一个基本的例子,但是如果需要的话,你可以把它构造成可定制的道具。 注意到有生命周期的警告,但它应该总是重新渲染路由器,就像在v2中一样。 这对于来自操作函数的API请求之后的redirect很有用。

 // browser router file... import createHistory from 'history/createBrowserHistory'; import { Router } from 'react-router'; export const history = createHistory(); export default class BrowserRouter extends Component { render() { return <Router history={history} children={this.props.children} /> } } // your main file... import BrowserRouter from './relative/path/to/BrowserRouter'; import { render } from 'react-dom'; render( <BrowserRouter> <App/> </BrowserRouter> ); // some file... where you don't have React instance references import { history } from './relative/path/to/BrowserRouter'; history.push('/sample'); 

最新的BrowserRouter扩展: https : //github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js

反应路由器V2

将一个新的状态推送到browserHistory实例:

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

参考: https : //github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfComponents.md

React Router 4包含一个withRouter HOC ,通过this.props可以访问history对象:

 import React from 'react' import {withRouter} from 'react-router-dom' class Foo extends Component { constructor(props) { super(props) this.goHome = this.goHome.bind(this) } goHome() { this.props.history.push('/') } render() { <div className="foo"> <button onClick={this.goHome} /> </div> } } export default withRouter(Foo) 

https://github.com/rackt/react-router/blob/bf89168acb30b6dc9b0244360bcbac5081cf6b38/examples/transitions/app.js#L50

或者你甚至可以尝试执行onClick(更猛烈的解决scheme):

 window.location.assign("/sample"); 

好吧,我想我能find一个适当的解决scheme。

现在,我不发送<Link/>作为文档的道具 ,而是发送<NextLink/>这是一个自定义包装的反应路由器链接。 通过这样做,我可以将右箭头作为链接结构的一部分,同时避免在Document对象中有路由代码。

更新的代码如下所示:

 //in NextLink.js var React = require('react'); var Right = require('./Right'); var NextLink = React.createClass({ propTypes: { link: React.PropTypes.node.isRequired }, contextTypes: { transitionTo: React.PropTypes.func.isRequired }, _onClickRight: function() { this.context.transitionTo(this.props.link.props.to); }, render: function() { return ( <div> {this.props.link} <Right onClick={this._onClickRight} /> </div> ); } }); module.exports = NextLink; ... //in MasterPage.js var sampleLink = <Link to="/sample">Go To Sample</Link> var nextLink = <NextLink link={sampleLink} /> <Document next={nextLink} /> //in Document.js ... var Document = React.createClass({ render: function() { return ( ... <div>{this.props.next}</div> ... ); } }); ... 

PS :如果您使用的是最新版本的react-router,则可能需要使用this.context.router.transitionTo而不是this.context.transitionTo 。 这个代码对于反应路由器版本0.12.X可以正常工作。

反应路由器4

您可以通过v4中的上下文轻松调用push方法:

this.context.router.push(this.props.exitPath);

上下文是:

 static contextTypes = { router: React.PropTypes.object, };