Higher-Order Component

Higher-Order Component

const CommentListWithSubscription = withSubscription(
  (DataSource) => DataSource.getComments()

const BlogPostWithSubscription = withSubscription(
  (DataSource, props) => DataSource.getBlogPost(props.id)

// This function takes a component...
function withSubscription(WrappedComponent, selectData) {
  // ...and returns another component...
  return class extends React.Component {
    constructor(props) {
      this.handleChange = this.handleChange.bind(this);
      this.state = {
        data: selectData(DataSource, props)

    componentDidMount() {
      // ... that takes care of the subscription...

    componentWillUnmount() {

    handleChange() {
        data: selectData(DataSource, this.props)

    render() {
      // ... and renders the wrapped component with the fresh data!
      // Notice that we pass through any additional props
      return <WrappedComponent data={this.state.data} {...this.props} />;

Is an advanced technique in React for reusing component logic.

Concretely, a higher-order component is a function that takes a component and returns a new component.

Convention: Pass Unrelated Props Through to the Wrapped Component

render() {
  // Filter out extra props that are specific to this HOC and shouldn't be
  // passed through
  const { extraProp, ...passThroughProps } = this.props;

  // Inject props into the wrapped component. These are usually state values or
  // instance methods.
  const injectedProp = someStateOrInstanceMethod;

  // Pass props to wrapped component
  return (

HOCs should pass through props that are unrelated to its specific concern because HOCs shouldn’t drastically alter its contract and it’s expected that the component returned from a HOC has a similar interface to the wrapped component.

Convention: Maximizing Composability

// Instead of doing this...
const EnhancedComponent = withRouter(connect(commentSelector)(WrappedComponent))

// ... you can use a function composition utility
// compose(f, g, h) is the same as (...args) => f(g(h(...args)))
const enhance = compose(
  // These are both single-argument HOCs
const EnhancedComponent = enhance(WrappedComponent)

Convention: Wrap the Display Name for Easy Debugging

function withSubscription(WrappedComponent) {
  class WithSubscription extends React.Component {/* ... */}
  WithSubscription.displayName = `WithSubscription(${getDisplayName(WrappedComponent)})`;
  return WithSubscription;

function getDisplayName(WrappedComponent) {
  return WrappedComponent.displayName || WrappedComponent.name || 'Component';

To ease debugging, choose a display name that communicates that it’s the result of a HOC.

Higher-Order Component — Structure map

Clickable & Draggable!

Higher-Order Component — Related pages: