How to push to History in React Router v4?

后端 未结 21 1852
不思量自难忘°
不思量自难忘° 2020-11-22 00:27

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. However, this isn

相关标签:
21条回答
  • 2020-11-22 01:24

    React Router v4 is fundamentally different from v3 (and earlier) and you cannot do browserHistory.push() like you used to.

    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. So a different instance will change the url but not update the <BrowserRouter>.
    • browserHistory is not exposed by react-router in v4, only in v2.

    Instead you have a few options to do this:

    • 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.

    0 讨论(0)
  • 2020-11-22 01:25

    Now with react-router v5 you can use the useHistory lifecycle hook like this:

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

    read more at: https://reacttraining.com/react-router/web/api/Hooks/usehistory

    0 讨论(0)
  • 2020-11-22 01:25

    Nasty question, took me quite a lot of time, but eventually, I solved it this way:

    Wrap your container with withRouter and pass history to your action in mapDispatchToProps function. In action use history.push('/url') to navigate.

    Action:

    export function saveData(history, data) {
      fetch.post('/save', data)
         .then((response) => {
           ...
           history.push('/url');
         })
    };
    

    Container:

    import { withRouter } from 'react-router-dom';
    ...
    const mapDispatchToProps = (dispatch, ownProps) => {
      return {
        save: (data) => dispatch(saveData(ownProps.history, data))}
    };
    export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Container));
    

    This is valid for React Router v4.x.

    0 讨论(0)
提交回复
热议问题