Clean β’ Professional
As React applications grow, multiple components often need to share common logic β like fetching data, handling mouse movements, or managing state.
Instead of duplicating that logic, React provides a pattern called Render Props, which allows you to share functionality between components in a clean and reusable way.
A Render Prop is a technique for sharing code between React components using a function that returns JSX.
Itβs called a render prop because a prop is used to tell a component what to render.
Example:
import React, { useState } from "react";
function MouseTracker({ render }) {
const [position, setPosition] = useState({ x: 0, y: 0 });
function handleMouseMove(event) {
setPosition({
x: event.clientX,
y: event.clientY,
});
}
return (
<div style={{ height: "200px" }} onMouseMove={handleMouseMove}>
{render(position)}
</div>
);
}
function App() {
return (
<MouseTrackerrender={({ x, y }) => (
<h3>
Mouse position: ({x}, {y})
</h3>
)}
/>
);
}
export default App;
MouseTracker component handles the logic for tracking mouse movement.render() prop.App) defines how the data is displayed.This keeps the logic reusable while allowing flexible UI rendering.
Render Props are great when you want to:
Example 2: Sharing Logic for Data Fetching
Hereβs how you can use render props to share data fetching functionality:
import React, { useEffect, useState } from "react";
function DataFetcher({ url, render }) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((result) => {
setData(result);
setLoading(false);
});
}, [url]);
return render({ data, loading });
}
function App() {
return (
<div>
<h2>Render Props Example β Posts</h2>
<DataFetcherurl="<https://jsonplaceholder.typicode.com/posts>"
render={({ data, loading }) =>
loading ? (
<p>Loading...</p>
) : (
<ul>
{data.slice(0, 5).map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
/>
</div>
);
}
export default App;
How it works:
DataFetcher component contains the reusable data-fetching logic.render prop.App decides how the data should look.Instead of using a render prop, you can use the children prop as a function.
This is another common pattern in React.
function MouseTracker({ children }) {
const [pos, setPos] = useState({ x: 0, y: 0 });
function handleMouseMove(e) {
setPos({ x: e.clientX, y: e.clientY });
}
return (
<div onMouseMove={handleMouseMove} style={{ height: "200px" }}>
{children(pos)}
</div>
);
}
function App() {
return (
<MouseTracker>
{({ x, y }) => (
<p>
Mouse coordinates: <strong>{x}, {y}</strong>
</p>
)}
</MouseTracker>
);
}
| Feature | Render Props | Higher-Order Components (HOC) |
|---|---|---|
| Definition | Uses a function prop to render content | Wraps a component in another function |
| Flexibility | Very flexible and explicit | May lead to nested components |
| Code Reuse | Great for state sharing and logic reuse | Great for enhancing components |
| Modern Use | Often replaced by custom hooks | Often replaced by hooks too |
Use Render Props when you need: