Order of Higher Order Components (HOC) matters

I’ve just learned the hard way that order of calling Higher Order Components (HOC) matters and can lead to hard to debug errors. I’ve used the Redux and React Router Dom. Started with Redux so I had component like so:

import react, {Component} from 'react'
import connect from 'react-redux/lib/connect/connect';

class Home extends Component {
    // ... chopped for brevity
}

export default connect(mapStateToProps)(Home);

Then in the component I wanted to navigate programmatically so I’ve used withRouter to get access to history object.

import react, {Component} from 'react'
import connect from 'react-redux/lib/connect/connect';
import { withRouter } from 'react-router-dom';

class Home extends Component {
    // ... chopped for brevity
    render(){
        // ... chopped for brevity

        <button onClick={() => {
            this.props.history.push('/some-page');
        }}>Go</button>
        // ... chopped for brevity
    }
}

export default connect(mapStateToProps)(withRouter(Home));

Well, I was really surprised and was scratching my head why the page is not showing, the url has changed, the history object was changed, but requested page was not there! After extensive search on the internet, I’ve found this GIT issue comment that resolved it to me. The problem was with the order! You have to call withRouter first.

import react, {Component} from 'react'
import connect from 'react-redux/lib/connect/connect';
import { withRouter } from 'react-router-dom';

class Home extends Component {
    // ... chopped for brevity
    render(){
        // ... chopped for brevity

        <button onClick={() => {
            this.props.history.push('/some-page');
        }}>Go</button>
        // ... chopped for brevity
    }
}

export default withRouter(
                    connect(mapStateToProps)(Home)
                );

Leave a Reply

Your email address will not be published. Required fields are marked *

*