Skip to content

React HOC simplified

Holding wraps

To explain Higher Order Components (HOCs), it's important to understand what higher order functions are in JavaScript.

Higher order function

A higher order function is a function that either:

  • accepts at least one function as argument, or

  • returns a function, or

  • both of the above

Higher Order Component (HOC)

A HOC is a function that takes a component as argument and returns a component. This pattern is commonly used to enhance components with additional props and/or functionality.

Let's take a look at an example. We have a Counter component that accepts 2 props; initialValue and log. The initialValue is used as the starting value of the counter. log is a function that logs out text.

function Counter({ initialValue, log }) {
  const [count, setCount] = useState(initialValue);

  const handleClick = () => {
    setCount((prevCount) => {
      const nextCount = prevCount + 1;
      log("Next count:", nextCount);
      return nextCount;
    });
  };

  return <button onClick={handleClick}>{count}</button>;
}

We're passing log as an argument because we want to log out the text we pass in, plus something else, like the current timestamp, and we might want this logging behavior in other components as well.

That's where a HOC is useful.

function withLog(WrappedComponent) {
  // adds timestamp to console.log
  const log = (...text) => {
    console.log(new Date().toISOString(), ...text);
  };

  return ({ ...wrappedComponentProps }) => (
    <WrappedComponent
      {...wrappedComponentProps}
      log={log}
    />
  );
}

Notice how withLog returns a component (i.e. a function that returns JSX) that accepts wrappedComponentProps? These are Counter's props. However, withLog is responsible for passing log to WrappedComponent.

Next, we need to call withLog with Counter as argument.

const EnhancedCounter = withLog(Counter);

function App() {
  return <EnhancedCounter initialValue={1} />;
}

When using EnhancedCounter, we don't pass in log as this is already taken care of by withLog.

References

If you want a deeper understanding of HOCs, check out React's official docs.