Back to results for “Hooks”
React › Render Props Pattern

How would you rewrite a render props component as a custom hook instead?

Advanced

Answer

You move the shared logic, like tracking state or subscribing to something, directly inside a custom hook, and return whatever data the component needs. The component using the hook then decides how to render that data directly in its own JSX, without needing an extra wrapping component or a function prop at all.
// Render props version
function MouseTracker({ render }) {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  return <div onMouseMove={(e) => setPosition({ x: e.clientX, y: e.clientY })}>{render(position)}</div>;
}

// Custom hook version, simpler and flatter
function useMousePosition() {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  useEffect(() => {
    function handleMove(e) { setPosition({ x: e.clientX, y: e.clientY }); }
    window.addEventListener('mousemove', handleMove);
    return () => window.removeEventListener('mousemove', handleMove);
  }, []);
  return position;
}
Real-world example A team refactors an older MouseTracker render props component into a simple useMousePosition custom hook, removing an unnecessary wrapping component and making the code easier for new developers to follow.

Common follow-ups: Are there still cases today where render props are a better choice than a custom hook?;What extra flexibility does the render props pattern offer that a hook alone cannot?