随着react-router
我可以使用Link
元素来创建这些原生处理react-router链接。
我在内部看到它调用this.context.transitionTo(...)
.
我想做一个导航。不是来自链接,而是来自下拉选择(例如)。我怎样才能在代码中做到这一点?什么是this.context
?
我看到了Navigation
mixin,但是我可以不用它mixins
吗?
随着react-router
我可以使用Link
元素来创建这些原生处理react-router链接。
我在内部看到它调用this.context.transitionTo(...)
.
我想做一个导航。不是来自链接,而是来自下拉选择(例如)。我怎样才能在代码中做到这一点?什么是this.context
?
我看到了Navigation
mixin,但是我可以不用它mixins
吗?
带有钩子的 React Router v5.1.0
useHistory
如果您使用 React > 16.8.0 和功能组件,则 React Router >5.1.0 中有一个新钩子。
import { useHistory } from "react-router-dom";
function HomeButton() {
const history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
react-router v4
使用 React Router v4,您可以采用三种方法在组件内进行编程路由。
withRouter
高阶组件。<Route>
context
.React Router 主要是history
库的包装器。history
使用浏览window.history
器和哈希历史记录为您处理与浏览器的交互。它还提供了一个内存历史,这对于没有全局历史的环境很有用。这在移动应用程序开发 ( react-native
) 和 Node.js 单元测试中特别有用。
一个history
实例有两种导航方法:push
和replace
。如果您将history
视为访问过的位置push
数组,replace
则会向该数组添加一个新位置,并将用新位置替换该数组中的当前位置。通常,您会希望push
在导航时使用该方法。
在 React Router 的早期版本中,您必须创建自己的history
实例,但在 v4 中<BrowserRouter>
,<HashRouter>
、 和<MemoryRouter>
组件将为您创建浏览器、哈希和内存实例。React Routerhistory
通过router
对象下的上下文使与路由器关联的实例的属性和方法可用。
withRouter
高阶组件的withRouter
高次成分将注入的history
对象作为所述部件的支柱。这允许您访问push
和replace
方法而无需处理context
.
import { withRouter } from 'react-router-dom'
// this also works with react-router-native
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
))
<Route>
该<Route>
组件不仅用于匹配位置。您可以渲染无路径路线,它会始终与当前位置匹配。该<Route>
组件传递与 相同的propswithRouter
,因此您将能够history
通过history
props访问这些方法。
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
)} />
)
但你可能不应该
最后一个选项是只有在您觉得使用 React 的上下文模型很舒服时才应该使用的选项(React 的 Context API 从 v16 开始是稳定的)。
const Button = (props, context) => (
<button
type='button'
onClick={() => {
// context.history.push === history.push
context.history.push('/new-location')
}}
>
Click Me!
</button>
)
// you need to specify the context type so that it
// is available within the component
Button.contextTypes = {
history: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
})
}
1 和 2 是最容易实现的选择,因此对于大多数用例,它们是您最好的选择。
React-Router v6+答案
您可以使用新的useNavigate
钩子。useNavigate
hook 返回一个可用于编程导航的函数。react-router文档中的示例
import { useNavigate } from "react-router-dom";
function SignupForm() {
let navigate = useNavigate();
async function handleSubmit(event) {
event.preventDefault();
await submitForm(event.target);
navigate("../success", { replace: true });
}
return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}
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 及更高版本中,使用历史记录作为组件的props。
class Example extends React.Component {
// use `this.props.history.push('/some/path')` here
};
注意:如果您的组件不是由 呈现的,则 this.props.history 不存在<Route>
。您应该使用<Route path="..." component={YourComponent}/>
在 YourComponent 中有 this.props.history
React-Router 3.0.0+答案
在 3.0 及更高版本中,使用路由器作为组件的props。
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
React-Router 2.4.0+答案
在 2.4 及更高版本中,使用高阶组件将路由器作为组件的props。
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 module,您可以使用它访问
import { browserHistory } from 'react-router'
现在您可以访问浏览器历史记录,因此您可以执行推送、替换等操作...例如:
browserHistory.push('/some/path')
React-Router 1.xx答案
我不会讨论升级细节。您可以在升级指南中阅读相关内容
关于这里问题的主要变化是从导航混合到历史的变化。现在它使用浏览器 historyAPI 来更改路由,所以我们pushState()
将从现在开始使用。
下面是一个使用 Mixin 的例子:
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
请注意,这History
来自rackt/history项目。不是来自 React-Router 本身。
如果您出于某种原因(可能是因为 ES6 类)不想使用 Mixin,那么您可以从this.props.history
. 只有路由器呈现的组件才能访问它。因此,如果您想在任何子组件中使用它,则需要通过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
或者你可以试试花哨的 ES6 class
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
注:如果您使用的终极版,有一个名为另一个项目 ReactRouter,终极版,为您提供终极版绑定ReactRouter,有些使用了同样的方法 做出react,终极版呢
React-Router-Redux 有一些可用的方法,允许从内部动作创建者进行简单的导航。这些对于在 React Native 中拥有现有架构的人特别有用,并且他们希望在 React Web 中使用相同的模式,同时将样板开销降至最低。
探索以下方法:
push(location)
replace(location)
go(number)
goBack()
goForward()
这是使用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
),推荐的导航方法是直接推入历史单例。您可以在Navigating outside of Components 文档中看到这一点。
相关摘录:
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
如果使用较新的 react-router API,则需要在组件内部使用history
from this.props
when :
this.props.history.push('/some/path');
它还提供pushState
但不推荐使用每个记录的警告。
如果使用react-router-redux
,它提供了一个push
你可以像这样调度的函数:
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
然而,这可能仅用于更改 URL,而不是实际导航到页面。
这是react-router v2.0.0
使用ES6执行此操作的方法。react-router
已经远离 mixin。
import React from 'react';
export default class MyComponent extends React.Component {
navigateToPage = () => {
this.context.router.push('/my-route')
};
render() {
return (
<button onClick={this.navigateToPage}>Go!</button>
);
}
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
}
最后,我喜欢有一个单一的历史对象,我什至可以携带外部组件。我喜欢有一个我按需导入的 history.js 文件,然后对其进行操作。
您只需要更改BrowserRouter
为路由器,并指定历史props。这不会为您带来任何改变,只是您拥有自己的历史对象,可以根据需要进行操作。
您需要安装history使用的库react-router
。
示例用法,ES6表示法:
历史.js
import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()
基本组件.js
import React, { Component } from 'react';
import history from './history';
class BasicComponent extends Component {
goToIndex(e){
e.preventDefault();
history.push('/');
}
render(){
return <a href="#" onClick={this.goToIndex}>Previous</a>;
}
}
如果您必须从实际从Route
组件渲染的组件中导航,您还可以从 props 访问历史记录,如下所示:
基本组件.js
import React, { Component } from 'react';
class BasicComponent extends Component {
navigate(e){
e.preventDefault();
this.props.history.push('/url');
}
render(){
return <a href="#" onClick={this.navigate}>Previous</a>;
}
}