Skip to content

Instantly share code, notes, and snippets.

@robinmonjo
Last active March 14, 2019 17:27
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save robinmonjo/2790fb319351843349cfec43213f4898 to your computer and use it in GitHub Desktop.
Save robinmonjo/2790fb319351843349cfec43213f4898 to your computer and use it in GitHub Desktop.
ES6 Higher Order Components

Redux higher order components

Sometimes we need to share props and behaviour between multiple components/containers. For that we can do a higher order component. Example:

Decorator component

Higher Order Component that will decorate other component:

import { Component } from "React";
import { connect } from "react-redux";

function Decorate(ComponentToDecorate) {
  class ComponentDecorated extends Component {
    constructor(props) {
      super(props);
    }

    componentDidMount() {
      // fetch data and stuff
    }

    render() {
      return <ComponentToDecorate {...this.props} />;
    }
  }

  function mapStateToProps(state) {
    return {
      // your shared props
    };
  }

  const mapDispatchToProps = {
    // your shared action call
  };

  return connect(mapStateToProps, mapDispatchToProps)(ComponentDecorated);
}

export default Decorate;

Decorated component:

The actual component that will inherite stuff from the Higher Order Component

import React, { Component } from "react";
import { connect } from "react-redux";
import Decorate from "Decorate.react";

class SomeComponent extends Component {

  constructor(props) {
    super(props);
  }

  componentDidMount() {
  }

  componentWillReceiveProps(nextProps) {
  }

  render() {
    <p> Hello </p>
  );
}

function mapStateToProps(state) {
  return {
    // component specific props
  };
}

const mapDispatchToProps = {
  // component specific action call
};

export default connect(mapStateToProps, mapDispatchToProps)(Decorate(SomeComponent));
@dkovacevic15
Copy link

dkovacevic15 commented Feb 6, 2018

Redux provides a compose utility function to make the syntax a little easier on the eyes. It takes functions as arguments, and returns a function that applies those functions right to left. That way, your line:

export default connect(mapStateToProps, mapDispatchToProps)(Decorate(SomeComponent));

would become

import { compose } from 'redux';
...
...
...
export default compose(
    connect(mapStateToProps, mapDispatchToProps),
    decorate
)(SomeComponent)

@rhomoelle
Copy link

Is there a reason you are wrapping the returned decorated component in the Decorator HOC in just another connect? I thought it receives that from export default connect(mapStateToProps, mapDispatchToProps)(Decorate(SomeComponent));.

@jordan-cutler
Copy link

@rhomoelle I think that's to do the overrides

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment