mediumReact#42

Higher-Order Component pattern

Prompt

Write a HOC called withLogging that logs "Component rendered" each time the wrapped component renders. Apply it to a simple Text component. Remember to forward props through.

Solution

function withLogging(WrappedComponent) {
  return function LoggedComponent(props) {
    console.log('Component rendered')
    return <WrappedComponent {...props} />
  }
}
Mentor's take

HOCs were the pre-hooks answer to sharing cross-cutting behavior — logging, auth gating, data subscription — without inheritance: a function that takes a component and returns a new component wrapping it. connect from React Redux and withRouter made the pattern famous.

The mechanics: withLogging runs once at definition time and returns LoggedComponent; the console.log sits in the returned component's render path, so it fires on every render of the wrapper. {...props} forwarding is non-negotiable — the wrapper must be transparent, or every HOC in the chain becomes a prop bottleneck. Production HOCs also set displayName for devtools and hoist static members; knowing those chores exist is part of the answer.

Two classic landmines: never call a HOC inside renderwithLogging(Hello) produces a brand-new component type each call, so reconciliation sees a different type every render and remounts the entire subtree, destroying its state. And HOCs stack into wrapper pyramids — five of them means five layers in devtools — which is precisely the pain hooks were designed to remove by making stateful logic a plain composable function.

Red flag: Presenting HOCs as today's default for logic reuse. The senior answer is historical placement: "I can write one, I maintain them in legacy code, but new cross-cutting logic becomes a custom hook."

Say it: "A HOC is a component-in, component-out factory — apply it at module scope, forward all props, and in modern code I'd reach for a custom hook instead of stacking wrappers."