The Render Props pattern is a technique for sharing code between React components using a prop whose value is a function. A component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic. This pattern provides a powerful way to share stateful logic while keeping components flexible and reusable.
The example below shows a MouseTracker component that tracks the mouse position and shares that data through a render prop. Move your mouse over the area to see it in action.
Move your mouse in this area!
Mouse position: (0, 0)
The same component can also be used with an explicit render prop:
The mouse coordinates are:
x: 0, y: 0
The same component can also be used with an explicit render prop:
Move your mouse inside this box
Current mouse position: (0, 0)
// MouseTracker.tsx
import React, { useState, ReactNode } from 'react';
// Type for mouse position
type MousePosition = {
x: number;
y: number;
};
// Props type for the MouseTracker component
type MouseTrackerProps = {
render?: (position: MousePosition) => ReactNode;
children?: (position: MousePosition) => ReactNode;
};
export const MouseTracker: React.FC<MouseTrackerProps> = ({ render, children }) => {
const [position, setPosition] = useState<MousePosition>({ x: 0, y: 0 });
const handleMouseMove = (event: React.MouseEvent) => {
const rect = event.currentTarget.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
setPosition({ x, y });
};
return (
<div onMouseMove={handleMouseMove}>
{render ? render(position) : children ? children(position) : null}
</div>
);
};
// Usage with children function:
// <MouseTracker>
// {(mousePosition) => (
// <p>Mouse position: {mousePosition.x}, {mousePosition.y}</p>
// )}
// </MouseTracker>
// Usage with render prop:
// <MouseTracker
// render={(mousePosition) => (
// <p>Mouse position: {mousePosition.x}, {mousePosition.y}</p>
// )}
// />