68

I just checked out HOC's in React. They are pretty cool. However, doesn't simply wrapping a component achieve the same result?

Higher Order Component

This simple HOC passes state as properties to the ComposedComponent

const HOC = ComposedComponent => class extends React.Component {

    ... lifecycle, state, etc;...

    render() {
      return (<ComposedComponent {...this.state} />);
    }      

}

Component Wrapping

This component passes state as properties to the child component

class ParentComponent extends React.Component {

    ... lifecycle, state, etc;...

    render() {
      return (
        <div>
          {React.cloneElement(this.props.children, { ...this.state })}  
        </div>
      );
    }      

}

Although usage is slightly different between the two, they both seem to be equally as reusable.

Where is the real difference between HOC's and composing components via this.props.children? Are there examples where you can only use one or the other? It is a better practice to use HOC's. Are these just choices that you have where you get to pick your preferred flavor?

Tabbyofjudah
  • 1,973
  • 3
  • 17
  • 29

2 Answers2

49

Higher-Order Components (HOC) and Container Components are different. They have different use cases and solve similar, but different problems.

HOC are like mixins. They are used to compose functionality that the decorated component is aware of. This is opposed to Container Components that wrap children and allow the children to be dumb (or not aware of the Container's decorated functionality).

It is true when transferring props, that Containers can add functionality to their children. But, this is usually in the form of props being passed down to the children. In Containers, this is also awkward because of the limitation that you cannot simply add props to an already created Element:

So, if you wanted to add a new prop to a child from this.props.children, you would have to use cloneElement. This is not as efficient because it means you have to re-create the elements.

Also, HOC is simply a way (factory) for creating Components. So, this can happen outside the render.

Davin Tryon
  • 66,517
  • 15
  • 143
  • 132
  • 1
    Can you please explain why " this is also awkward because of the limitation that you cannot simply add props to an already created Element"? – Morgan Cheng Dec 27 '16 at 02:41
  • 4
    I think Davin means that HOCs are called with component instances, to which the HOC can inject props before the component is rendered. Container components are called with the result of rendering a component instance, not the component instance itself. – Chris Noreikis Jun 02 '17 at 16:14
  • So it would not be uncommon to see both of these techniques in the same project? Containers holding the logic of its 'dumb' children components, and any of the components implementing HOCs to add similar but non-domain-specific functionality? – user Jul 22 '17 at 06:13
  • 2
    this is a good answer, I think "that the decorated component is aware of" part should be **emphasised** as that was crucial for me to distinguish between the two. – mavili Oct 02 '19 at 14:52
  • 4
    what do you mean when you say the decorated component is aware of the HOC's functionality? I'm having trouble understanding this. – Sendai Jan 09 '20 at 11:27
  • Can you explain "that the decorated component is aware of" – targhs Nov 02 '22 at 08:27
8

I just wanted to add that when you need to dynamic higher order components the Container approach works better.

If you e.g have 4 elements to render that could have a HOC defined, you would like to create the Higher Order Component inside render, but since calling higher order components inside render causes the <HigherOrderComponent/>'s to remount on every render this becomes a very bad Idea.

This is documented here; https://github.com/facebook/react/blob/044015760883d03f060301a15beef17909abbf71/docs/docs/higher-order-components.md#dont-use-hocs-inside-the-render-method.

But in general I would go for the HOC approach.

pudgereyem
  • 131
  • 1
  • 3