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

在当前版本的React Router(v3)中,我可以接受服务器响应,并使用browserHistory.push转到相应的响应页面。 然而,这在v4中是不可用的,我不确定处理这个问题的适当方法是什么。

在此示例中,使用Redux时,components / app-product-form.js在用户提交表单时调用this.props.addProduct(props) 。 当服务器返回成功时,用户将被带到购物车页面。

// 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 v4与v3(及更早版本)有着根本的不同,并且您不能像过去那样执行browserHistory.push()

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

  • 创建一个新的browserHistory将不起作用,因为<BrowserRouter>创建它自己的历史实例,并监听它的变化。 所以不同的实例会改变url,但不会更新<BrowserRouter>
  • browserHistory不会被v4中的react-router暴露,只能在v2中暴露。

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

  • 使用withRouter高阶组件

    相反,您应该使用withRouter高阶组件,并将其包装到将推向历史记录的组件。 例如:

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

    查看官方文档获取更多信息:

    您可以通过withRouter高阶组件访问history对象的属性和最近的<Route> match 。 withRouter将每次使用与<Route> render props: { match, location, history }相同的道具更改路线时重新呈现其组件。


  • 使用context API

    使用上下文可能是最简单的解决方案之一,但作为一个实验性API,它不稳定且不受支持。 只有在其他一切都失败时才使用它。 这是一个例子:

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

    查看关于上下文的官方文档

    如果你希望你的应用程序稳定,不要使用上下文。 这是一个实验性的API,它很可能在未来的React版本中被打破。

    如果您坚持使用上下文而不管这些警告,请尝试将上下文的使用隔离到一个小区域,并尽可能避免直接使用上下文API,以便在API更改时更容易升级。


  • 您可以在组件外使用history方法。 试试以下方法。

    首先,创建一个使用历史包的history对象:

    // src/history.js
    
    import { createBrowserHistory } from 'history';
    
    export default createBrowserHistory();
    

    然后将它包装在<Router>请注意 ,您应该使用import { Router }而不是import { BrowserRouter as Router } ):

    // src/index.jsx
    
    // ...
    import { Router, Route, Link } from 'react-router-dom';
    import history from './history';
    
    ReactDOM.render(
      <Provider store={store}>
        <Router history={history}>
          <div>
            <ul>
              <li><Link to="/">Home</Link></li>
              <li><Link to="/login">Login</Link></li>
            </ul>
            <Route exact path="/" component={HomePage} />
            <Route path="/login" component={LoginPage} />
          </div>
        </Router>
      </Provider>,
      document.getElementById('root'),
    );
    

    从任何地方更改您的当前位置,例如:

    // src/actions/userActionCreators.js
    
    // ...
    import history from '../history';
    
    export function login(credentials) {
      return function (dispatch) {
        return loginRemotely(credentials)
          .then((response) => {
            // ...
            history.push('/');
          });
      };
    }
    

    UPD:你也可以在React Router FAQ中看到一个稍微不同的例子。


    我是这么做的:

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

    使用this.props.history.push('/cart'); 重定向到购物车页面,它将被保存在历史对象中。

    享受,迈克尔。

    链接地址: http://www.djcxy.com/p/52135.html

    上一篇: How to push to History in React Router v4?

    下一篇: Persistent Navigation React