REACT Contents

Render Props and Pattern Alternatives

Render props share behavior while keeping rendering flexible, but can create nesting and identity churn. Learn typed render props, stabilization, and when to prefer hooks or compound components.

On this page

What Render Props Provide

  • Behavior reuse without forcing markup structure.
  • A clear contract: payload in, UI out.
  • Works well for cross cutting UI behaviors (measurement, hover, async state).

Primary Costs

  • Nested JSX reduces readability at scale.
  • New function identities can retrigger effects and rerenders.
  • Harder to compose multiple behaviors without deep nesting.

Typed Render Prop Contract

type HoverPayload = {
  isHover: boolean;
  bind: {
    onMouseEnter: () => void;
    onMouseLeave: () => void;
  };
};

function Hover({ children }: { children: (p: HoverPayload) => React.ReactNode }) {
  const [isHover, setIsHover] = React.useState(false);

  const bind = React.useMemo(() => {
    return {
      onMouseEnter: () => setIsHover(true),
      onMouseLeave: () => setIsHover(false),
    };
  }, []);

  return <>{children({ isHover, bind })}</>;
}

Usage Example

<Hover>
  {(h) => (
    <div {...h.bind}>
      {h.isHover ? "Hovering" : "Idle"}
    </div>
  )}
</Hover>

Alternatives and When to Use Them

  • Custom hook: best default for behavior reuse, avoids nesting.
  • Compound components: best when you need structured composition with coordination.
  • HOC: legacy pattern, can work but often complicates typing and debugging.
  • Inline logic: best for one off behavior to keep code simple.

Hook Alternative

function useHover() {
  const [isHover, setIsHover] = React.useState(false);
  const bind = React.useMemo(() => {
    return {
      onMouseEnter: () => setIsHover(true),
      onMouseLeave: () => setIsHover(false),
    };
  }, []);
  return { isHover, bind };
}

Operational Rules

  • Keep render prop payload minimal.
  • Stabilize functions that flow into dependency arrays.
  • Prefer hooks when nesting exceeds one level.

Failure Modes

  • Repeated effects because render prop function identity changes upstream.
  • Uncontrolled rerenders from payload objects recreated each render.
  • Deep nesting that hides business logic and makes incidents harder to debug.

Code Review Checklist

  • Pattern choice is justified against hooks and compound components.
  • Payload is narrow and stable.
  • Nesting depth remains readable.