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)
或者你甚至可以尝试执行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, };