本文翻译自:How to push to History in React Router v4?
In the current version of React Router (v3) I can accept a server response and use browserHistory.push
to go to the appropriate response page. 在当前版本的React Router(v3)中,我可以接受服务器响应并使用browserHistory.push
转到相应的响应页面。 However, this isn't available in v4, and I'm not sure what the appropriate way to handle this is. 但是,这在v4中不可用,我不确定哪种适当的处理方式。
In this example, using Redux, components/app-product-form.js calls this.props.addProduct(props)
when a user submits the form. 在此示例中,使用Redux,当用户提交表单时, components / app-product-form.js调用this.props.addProduct(props)
。 When the server returns a success, the user is taken to the Cart page. 服务器返回成功后,该用户将被带到“购物车”页面。
// actions/index.js
export function addProduct(props) {
return dispatch =>
axios.post(`${ROOT_URL}/cart`, props, config)
.then(response => {
dispatch({ type: types.AUTH_USER });
localStorage.setItem('token', response.data.token);
browserHistory.push('/cart'); // no longer in React Router V4
});
}
How can I make a redirect to the Cart page from function for React Router v4? 如何从React Router v4的功能重定向到购物车页面?
#1楼
参考:https://stackoom.com/question/2tAVt/如何在React-Router-v-中推送到历史记录
#2楼
React Router v4 is fundamentally different from v3 (and earlier) and you cannot do browserHistory.push()
like you used to. React Router v4从根本上不同于v3(及更早版本),并且您无法像以前那样执行browserHistory.push()
。
This discussion seems related if you want more info: 如果您需要更多信息,则此讨论似乎相关:
- Creating a new
browserHistory
won't work because<BrowserRouter>
creates its own history instance, and listens for changes on that. 创建一个新的browserHistory
不会起作用,因为<BrowserRouter>
创造自己的历史实例,并在该变化倾听。 So a different instance will change the url but not update the<BrowserRouter>
. 因此,其他实例将更改URL,但不会更新<BrowserRouter>
。browserHistory
is not exposed by react-router in v4, only in v2. 在v4中,react-router不公开browserHistory
,仅在v2中。
Instead you have a few options to do this: 取而代之的是,您有几种选择可以执行此操作:
Use the
withRouter
high-order component 使用withRouter
高阶组件Instead you should use the
withRouter
high order component, and wrap that to the component that will push to history. 相反,您应该使用withRouter
高阶组件,并将其包装到将推送到历史记录的组件中。 For example: 例如:import React from "react"; import { withRouter } from "react-router-dom"; class MyComponent extends React.Component { ... myFunction() { this.props.history.push("/some/Path"); } ... } export default withRouter(MyComponent);
Check out the official documentation for more info: 查看官方文档以获取更多信息:
You can get access to the
history
object's properties and the closest<Route>
'smatch
via the withRouter higher-order component. 您可以通过withRouter高阶组件访问history
对象的属性和最接近的<Route>
match
。 withRouter will re-render its component every time the route changes with the same props as<Route>
render props:{ match, location, history }
. 每当路线更改时,withRouter都会使用与<Route>
渲染道具相同的道具来重新渲染其组件:{ match, location, history }
。
Use the
context
API 使用context
APIUsing the context might be one of the easiest solutions, but being an experimental API it is unstable and unsupported. 使用上下文可能是最简单的解决方案之一,但是作为实验性API,它是不稳定且不受支持的。 Use it only when everything else fails. 仅在其他所有操作失败时才使用它。 Here's an example: 这是一个例子:
import React from "react"; import PropTypes from "prop-types"; class MyComponent extends React.Component { static contextTypes = { router: PropTypes.object } constructor(props, context) { super(props, context); } ... myFunction() { this.context.router.history.push("/some/Path"); } ... }
Have a look at the official documentation on context: 看一下有关上下文的官方文档 :
If you want your application to be stable, don't use context. 如果您希望应用程序稳定,请不要使用上下文。 It is an experimental API and it is likely to break in future releases of React. 这是一个实验性的API,可能会在React的未来版本中中断。
If you insist on using context despite these warnings, try to isolate your use of context to a small area and avoid using the context API directly when possible so that it's easier to upgrade when the API changes. 如果尽管这些警告仍坚持使用上下文,请尝试将上下文的使用隔离在较小的区域,并在可能的情况下避免直接使用上下文API,以便在API更改时更容易升级。
#3楼
This is how I did it: 这是我的方法:
import React, {Component} from 'react';
export default class Link extends Component {
constructor(props) {
super(props);
this.onLogout = this.onLogout.bind(this);
}
onLogout() {
this.props.history.push('/');
}
render() {
return (
<div>
<h1>Your Links</h1>
<button onClick={this.onLogout}>Logout</button>
</div>
);
}
}
Use this.props.history.push('/cart');
使用this.props.history.push('/cart');
to redirect to cart page it will be saved in history object. 重定向到购物车页面,它将保存在历史记录对象中。
Enjoy, Michael. 享受,迈克尔。
#4楼
this.context.history.push
will not work. this.context.history.push
将不起作用。
I managed to get push working like this: 我设法使推像这样工作:
static contextTypes = {
router: PropTypes.object
}
handleSubmit(e) {
e.preventDefault();
if (this.props.auth.success) {
this.context.router.history.push("/some/Path")
}
}
#5楼
If you are using Redux, then I would recommend using npm package react-router-redux . 如果您使用的是Redux,那么我建议您使用npm软件包react-router-redux 。 It allows you to dispatch Redux store navigation actions. 它允许您调度Redux商店导航操作。
You have to create store as described in their Readme file . 您必须按照其自述文件中的说明创建存储。
The easiest use case: 最简单的用例:
import { push } from 'react-router-redux'
this.props.dispatch(push('/second page'));
Second use case with Container/Component: 容器/组件的第二个用例:
Container: 容器:
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import Form from '../components/Form';
const mapDispatchToProps = dispatch => ({
changeUrl: url => dispatch(push(url)),
});
export default connect(null, mapDispatchToProps)(Form);
Component: 零件:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class Form extends Component {
handleClick = () => {
this.props.changeUrl('/secondPage');
};
render() {
return (
<div>
<button onClick={this.handleClick}/>
</div>Readme file
);
}
}
#6楼
In this case you're passing props to your thunk. 在这种情况下,您会将道具传递给重击。 So you can simply call 所以你可以简单地打电话
props.history.push('/cart')
If this isn't the case you can still pass history from your component 如果不是这种情况,您仍然可以通过组件传递历史记录
export function addProduct(data, history) {
return dispatch => {
axios.post('/url', data).then((response) => {
dispatch({ type: types.AUTH_USER })
history.push('/cart')
})
}
}