在当前版本的React Router (v3)中,我可以接受服务器响应并使用browserHistory。点击进入相应的响应页面。但是,这在v4中是不可用的,我不确定处理它的适当方法是什么。

在这个例子中,使用Redux, components/app-product-form.js在用户提交表单时调用this.props. addproduct (props)。当服务器返回成功时,用户将被带到Cart页面。

// 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
      });
}

如何从React Router v4的函数重定向到购物车页面?


当前回答

所以我的做法是: -而不是使用历史重定向。推送,我只是使用从react-router-dom重定向组件 当使用这个组件时,你只需要传递push=true,它就会处理剩下的事情

import * as React from 'react';
import { Redirect } from 'react-router-dom';
class Example extends React.Component {
  componentDidMount() {
    this.setState({
      redirectTo: '/test/path'
    });
  }

  render() {
    const { redirectTo } = this.state;

    return <Redirect to={{pathname: redirectTo}} push={true}/>
  }
}

其他回答

如果你正在使用Redux,那么我建议使用npm包react-router-redux。它允许您分派Redux存储导航操作。

你必须在他们的自述文件中创建存储。

最简单的用例:

import { push } from 'react-router-redux'

this.props.dispatch(push('/second page'));

容器/组件的第二个用例:

容器:

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);

组件:

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
    );
  }
}

现在在react-router v5中,你可以像这样使用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>
  );
}

详情请访问:https://reacttraining.com/react-router/web/api/Hooks/usehistory

React Router v4与v3(以及更早的版本)有本质上的不同,你不能像以前那样执行browserHistory.push()。

如果你想了解更多信息,这个讨论似乎是相关的:

创建一个新的browserHistory将不起作用,因为<BrowserRouter>创建了自己的历史实例,并侦听其上的更改。因此,不同的实例将更改url,但不更新<BrowserRouter>。 react-router不会在v4中公开browserHistory,只会在v2中公开。


相反,你有几个选择来做到这一点:

Use the withRouter high-order component Instead you should use the withRouter high order component, and wrap that to the component that will push to history. 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 will re-render its component every time the route changes with the same props as <Route> render props: { match, location, history }.


Use the context API Using the context might be one of the easiest solutions, but being an experimental API it is unstable and unsupported. 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. 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.

在这种情况下,你将道具传递给你的坦克。所以你可以简单地打电话

props.history.push('/cart')

如果情况并非如此,您仍然可以从组件传递历史记录

export function addProduct(data, history) {
  return dispatch => {
    axios.post('/url', data).then((response) => {
      dispatch({ type: types.AUTH_USER })
      history.push('/cart')
    })
  }
}

使用回调。这对我很管用!

export function addProduct(props, callback) {
  return dispatch =>
    axios.post(`${ROOT_URL}/cart`, props, config)
    .then(response => {
    dispatch({ type: types.AUTH_USER });
    localStorage.setItem('token', response.data.token);
    callback();
  });
}

在组件中,你只需要添加回调

this.props.addProduct(props, () => this.props.history.push('/cart'))