Using compose() and connect() together in React JS redux

compose doesn't get rid of the pattern of passing a function to the result of a function call, but it reduces its use to one.

Only one HOC, no gain from using compose:

// withStyles, without compose
export default withStyles(styles)(MyComponent)

// withStyles, with compose
export default compose(withStyles(styles))(MyComponent)

// connect, without compose
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)

// connect, with compose
export default compose(connect(mapStateToProps, mapDispatchToProps))(MyComponent)

Note that starting another function call immediately after a function call, which only recently came into fashion, is still there with compose.

With two HOCs there is a gain from compose because the nesting of parens is less:

// two HOCs, without compose
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(MyComponent))

// two HOCs, with compose
export default compose(connect(mapStateToProps, mapDispatchToProps), withStyles(styles))(MyComponent)

This still can be hard to follow if you aren't used to a nameless function being called immediately after it's created. If you prefer you can give a name to it:

// two HOCs, with compose
const enhance = compose(connect(mapStateToProps, mapDispatchToProps, withStyles(styles));
// export default enhance(MyComponent);

I prefer to use compose when there is more than one HOC, and to use it directly. I think cutting down on the nesting is useful but giving it a generic name like enhance is unnecessary.


const enhance = compose(
    withRouter,
    withStyles(styles, 'some style'),
    connect(mapStateToProps, mapDispatchToProps),
    ....

export default enhance(MyComponent);

import {bindActionCreators} from 'redux';
import compose from 'recompose/compose';
import { connect } from 'react-redux';
...Other code here
function mapStateToProps(state) {
    return {
        //return state
    }
}
function mapDispatchToProps(){
    return bindActionCreators({
        //actions
    }, dispatch);
}
Login.propTypes = {
    classes: PropTypes.shape({}).isRequired,
    width: PropTypes.string.isRequired
};
export default compose(withWidth(), withStyles(styles, {withTheme: true}), connect(mapStateToProps, mapDispatchToProps))(Login);

I hope this solves your problem.