如何在React Router v4中推送到历史记录?

本文翻译自: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> 's match 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 API

    Using 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')
    })
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值