Javascript React-router:如何手动调用 Link?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29244731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React-router: How to manually invoke Link?
提问by Alan Souza
I'm new to ReactJS and to React-Router. I have a component that receives through props a <Link/>object from react-router. Whenever the user clicks on a 'next' button inside this component I want to invoke <Link/>object manually.
我是 ReactJS 和 React-Router 的新手。我有一个组件,它通过 props<Link/>从react-router接收一个对象。每当用户单击此组件内的“下一步”按钮时,我都想<Link/>手动调用对象。
Right now, I'm using refsto access the backing instanceand manually clicking on the 'a' tag that <Link/>generates.
现在,我正在使用refs访问支持实例并手动单击<Link/>生成的“a”标签。
Question:Is there a way to manually invoke the Link (e.g. this.props.next.go)?
问题:有没有办法手动调用链接(例如this.props.next.go)?
This is the current code I have:
这是我目前的代码:
//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>
...
);
}
});
...
This is the code I would like to have:
这是我想要的代码:
//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>
...
);
}
});
...
回答by Matt Lo
React Router v4 - Redirect Component (updated 2017/04/15)
React Router v4 - 重定向组件(2017/04/15 更新)
The v4 recommended way is to allow your render method to catch a redirect. Use state or props to determine if the redirect component needs to be shown (which then trigger's a redirect).
v4 推荐的方法是允许您的渲染方法捕获重定向。使用 state 或 props 来确定是否需要显示重定向组件(然后触发重定向)。
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>;
}
Reference: https://reacttraining.com/react-router/web/api/Redirect
参考:https: //reacttraining.com/react-router/web/api/Redirect
React Router v4 - Reference Router Context
React Router v4 - 参考路由器上下文
You can also take advantage of Router's context that's exposed to the React component.
您还可以利用Router暴露给 React 组件的上下文。
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');
}
This is how <Redirect />works under the hood.
这就是<Redirect />引擎盖下的工作方式。
参考:https: //github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Redirect.js#L46,L60
React Router v4 - Externally Mutate History Object
React Router v4 - 外部变异历史对象
If you still need to do something similar to v2's implementation, you can create a copy of BrowserRouterthen expose the historyas an exportable constant. Below is a basic example but you can compose it to inject it with customizable props if needed. There are noted caveats with lifecycles, but it should always rerender the Router, just like in v2. This can be useful for redirects after an API request from an action function.
如果你仍然需要做一些类似于 v2 的实现,你可以创建一个副本,BrowserRouter然后将 公开history为一个可导出的常量。下面是一个基本示例,但如果需要,您可以编写它以将其注入可自定义的道具。有关于生命周期的注意事项,但它应该总是重新渲染路由器,就像在 v2 中一样。这对于在来自操作函数的 API 请求之后重定向非常有用。
// 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');
Latest BrowserRouterto extend: https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js
最新BrowserRouter扩展:https: //github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/BrowserRouter.js
React Router v2
反应路由器 v2
Push a new state to the browserHistoryinstance:
将新状态推送到browserHistory实例:
import {browserHistory} from 'react-router';
// ...
browserHistory.push('/sample');
Reference: https://github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfComponents.md
参考:https: //github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfComponents.md
回答by aw04
React Router 4 includes a withRouterHOCthat gives you access to the historyobject via this.props:
React Router 4 包含一个withRouter HOC,它使您可以history通过this.props以下方式访问对象:
import React, {Component} 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)
回答by Paulo Mateus
In the version 5.x, you can use useHistoryhook of react-router-dom:
在5.x 版本中,您可以使用以下useHistory钩子react-router-dom:
// Sample extracted from https://reacttraining.com/react-router/core/api/Hooks/usehistory
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
回答by grechut
or you can even try executing onClick this (more violent solution):
或者你甚至可以尝试执行 onClick 这个(更暴力的解决方案):
window.location.assign("/sample");
回答by Alan Souza
Ok, I think I was able to find a proper solution for that.
好的,我想我能够为此找到合适的解决方案。
Now, instead of sending <Link/>as propto Document, I send <NextLink/>which is a custom wrapper for the react-router Link. By doing that, I'm able to have the right arrow as part of the Link structure while still avoiding to have routing code inside Document object.
现在,我没有将其<Link/>作为道具发送到 Document,而是发送<NextLink/>它是 react-router 链接的自定义包装器。通过这样做,我可以将右箭头作为链接结构的一部分,同时仍然避免在 Document 对象中包含路由代码。
The updated code looks like follows:
更新后的代码如下所示:
//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>
...
);
}
});
...
P.S: If you are using the latest version of react-router you may need to use this.context.router.transitionToinstead of this.context.transitionTo. This code will work fine for react-router version 0.12.X.
PS:如果您使用的是最新版本的反应,路由器,你可能需要使用this.context.router.transitionTo代替this.context.transitionTo。此代码适用于 react-router 版本 0.12.X。
回答by Chris
React Router 4
反应路由器 4
You can easily invoke the push method via context in v4:
您可以通过 v4 中的上下文轻松调用 push 方法:
this.context.router.push(this.props.exitPath);
this.context.router.push(this.props.exitPath);
where context is:
上下文是:
static contextTypes = {
router: React.PropTypes.object,
};
回答by taggartJ
again this is JS :) this still works ....
这又是 JS :) 这仍然有效....
var linkToClick = document.getElementById('something');
linkToClick.click();
<Link id="something" to={/somewhaere}> the link </Link>

