通过react-router
,我可以使用Link
元素来创建由react router自然处理的链接。
我看到它在内部调用`this.context.transitionTo(...)'。
我想做一个导航,但不是从一个链接,而是从一个下拉选择,例如。我怎样才能在代码中做到这一点?什么是this.context
?
我看到了Navigation
混合器,但是我可以在没有混合器的情况下做这个吗?
React-Router 5.1.0+答案(使用钩子和React >16.8)。
你可以在功能组件和程序化导航上使用新的useHistory
钩子。
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
// use history.push('/some/path') here
};
React-Router 4.0.0+答案
在4.0及以上版本中,使用历史记录作为你的组件的一个道具。
class Example extends React.Component {
// use `this.props.history.push('/some/path')` here
};
注意:如果你的组件不是由<Route>
渲染的,那么this.props.history就不存在。你应该使用<Route path="..."component={YourComponent}/>
来在YourComponent中拥有this.props.history。
React-Router 3.0.0+ 回答
在3.0及以上版本中,使用路由器作为你的组件的一个道具。
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
React-Router 2.4.0+答案
在2.4及以上版本中,使用高阶组件来获得路由器作为你的组件的一个道具。
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
var DecoratedExample = withRouter(Example);
// PropTypes
Example.propTypes = {
router: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
}).isRequired
};
React-Router 2.0.0+答案
这个版本向后兼容1.x版本,所以不需要升级指南。只需浏览一下例子就够了。
也就是说,如果你想切换到新的模式,路由器内部有一个browserHistory模块,你可以用它来访问
import { browserHistory } from 'react-router'
。
现在你可以访问你的浏览器历史,所以你可以做推送、替换等事情。比如说。
browserHistory.push('/some/path')
。
React-Router 1.x.x 回答
我不打算谈升级的细节。你可以在升级指南中阅读相关内容。
关于这里的问题,主要的变化是将导航混合器改为历史。现在它使用浏览器的historyAPI来改变路线,所以我们从现在开始将使用pushState()
。
这里有一个使用混合器的例子。
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
注意,这个 "历史 "来自rackt/history项目。而不是来自React-Router本身。
如果你因为某些原因不想使用Mixin(也许是因为ES6类),那么你可以从this.props.history
中访问你从路由器得到的历史。它将只被你的Router渲染的组件所访问。所以,如果你想在任何子组件中使用它,它需要通过props
作为一个属性传递下去。
你可以在他们的1.0.x 文档中阅读更多关于新版本的信息。
它建议抓取一个引用history = createHistory()
,并对其调用replaceState
。
React-Router 0.13.x 回答
我遇到了同样的问题,只能通过react-router中的Navigation mixin找到解决方案。
我是这样做的
import React from 'react';
import {Navigation} from 'react-router';
let Authentication = React.createClass({
mixins: [Navigation],
handleClick(e) {
e.preventDefault();
this.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
我能够调用transitionTo()
而不需要访问.context
。
或者你可以试试花哨的ES6class
。
import React from 'react';
export default class Authentication extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
}
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
}
Authentication.contextTypes = {
router: React.PropTypes.func.isRequired
};
React-Router-Redux
注意:如果你使用Redux,还有一个项目叫做 React-Router-Redux,它给了你 ReactRouter的redux绑定,使用与ReactRouter相同的方法。 React-Redux的做法。
React-Router-Redux有一些可用的方法,允许从动作创建者内部进行简单的导航。这些方法对于在React Native中已有架构的人来说特别有用,他们希望在React Web中使用同样的模式,并将模板开销降到最低。
探索以下方法。
push(location)
go(number)
下面是一个使用实例,使用Redux-Thunk。
./actioncreators.js
import { goBack } from 'react-router-redux'
export const onBackPress = () => (dispatch) => dispatch(goBack())
./viewcomponent.js
<button
disabled={submitting}
className="cancel_button"
onClick={(e) => {
e.preventDefault()
this.props.onBackPress()
}}
>
CANCEL
</button>
React-Router v2
对于最新的版本(v2.0.0-rc5
),推荐的导航方法是直接推送到历史单机上。你可以在组件之外的导航文档中看到这个操作。
相关摘录。
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
如果使用较新的react-router API,你需要在组件内部使用this.props
的history
,这样。
this.props.history.push('/some/path');
它还提供了pushState
,但根据记录的警告,这已被废弃。
如果使用react-router-redux
,它提供了一个push
函数,你可以像这样调度。
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
然而,这可能只用于改变URL,而不是实际导航到该页面。
警告:本答案仅涵盖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>);
}
});
上下文的问题是,除非你在类上定义`contextTypes',否则它是无法访问的。
至于什么是context,它是一个对象,就像props一样,从父辈传到子辈,但它是隐式传下来的,不用每次都重新声明props。参见https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html