Render Props Pattern
Master the render props pattern for sharing behavior between components. This is a foundational concept in component-based UI development that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world React experience. Take your time with each section and practice the examples
70 min•By Priygop Team•Last updated: Feb 2026
What are Render Props?
Render props is a technique for sharing code between React components using a prop whose value is a function. This pattern allows components to share behavior while maintaining flexibility in how they render.
Basic Render Props
Example
// Basic render props example
import React, { useState } from 'react';
function MouseTracker({ render }) {
const [position, setPosition] = useState({ x: 0, y: 0 });
const handleMouseMove = (event) => {
setPosition({
x: event.clientX,
y: event.clientY
});
};
return (
<div onMouseMove={handleMouseMove} style={{ height: '100vh' }}>
{render(position)}
</div>
);
}
// Usage
function App() {
return (
<MouseTracker
render={({ x, y }) => (
<div>
<h1>Mouse Position</h1>
<p>X: {x}, Y: {y}</p>
</div>
)}
/>
);
}
// Another example with data fetching
function DataFetcher({ url, render }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
React.useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url);
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return render({ data, loading, error });
}
// Usage
function UserList() {
return (
<DataFetcher
url="/api/users"
render={({ data, loading, error }) => {
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!data) return <div>No data</div>;
return (
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}}
/>
);
}Advanced Render Props
Example
// Advanced render props with multiple behaviors
import React, { useState, useEffect } from 'react';
function Form({ initialValues = {}, onSubmit, children }) {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState({});
const [touched, setTouched] = useState({});
const handleChange = (name, value) => {
setValues(prev => ({ ...prev, [name]: value }));
if (touched[name]) {
// Clear error when user starts typing
setErrors(prev => ({ ...prev, [name]: '' }));
}
};
const handleBlur = (name) => {
setTouched(prev => ({ ...prev, [name]: true }));
};
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(values);
};
const getFieldProps = (name) => ({
value: values[name] || '',
onChange: (e) => handleChange(name, e.target.value),
onBlur: () => handleBlur(name),
error: errors[name],
touched: touched[name]
});
return (
<form onSubmit={handleSubmit}>
{children({ getFieldProps, values, errors, touched })}
</form>
);
}
// Usage
function LoginForm() {
const handleSubmit = (values) => {
console.log('Form submitted:', values);
};
return (
<Form
initialValues={{ email: '', password: '' }}
onSubmit={handleSubmit}
>
{({ getFieldProps, errors, touched }) => (
<>
<div>
<input
type="email"
placeholder="Email"
{...getFieldProps('email')}
/>
{touched.email && errors.email && (
<span className="error">{errors.email}</span>
)}
</div>
<div>
<input
type="password"
placeholder="Password"
{...getFieldProps('password')}
/>
{touched.password && errors.password && (
<span className="error">{errors.password}</span>
)}
</div>
<button type="submit">Login</button>
</>
)}
</Form>
);
}
// Toggle component with render props
function Toggle({ children }) {
const [on, setOn] = useState(false);
const toggle = () => setOn(!on);
const reset = () => setOn(false);
return children({ on, toggle, reset });
}
// Usage
function ToggleExample() {
return (
<Toggle>
{({ on, toggle, reset }) => (
<div>
<button onClick={toggle}>
{on ? 'ON' : 'OFF'}
</button>
<button onClick={reset}>Reset</button>
<p>Toggle is {on ? 'ON' : 'OFF'}</p>
</div>
)}
</Toggle>
);
}