Advanced Render Props
Learn the Render Props pattern to share code between components using a function as a child pattern.
90 min•By Priygop Team•Last updated: Feb 2026
Understanding 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 logic while maintaining flexibility.
Basic Render Props Implementation
Example
// Basic render props example
const Mouse = ({ render }) => {
const [position, setPosition] = useState({ x: 0, y: 0 });
const handleMouseMove = (event) => {
setPosition({
x: event.clientX,
y: event.clientY
});
};
return (
<div onMouseMove={handleMouseMove}>
{render(position)}
</div>
);
};
// Usage
<Mouse render={({ x, y }) => (
<div>
Mouse position: {x}, {y}
</div>
)} />Advanced Render Props Patterns
Example
// Data fetching with render props
const DataFetcher = ({ url, children }) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(error => {
setError(error);
setLoading(false);
});
}, [url]);
return children({ data, loading, error });
};
// Usage
<DataFetcher url="/api/users">
{({ data, loading, error }) => {
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <UserList users={data} />;
}}
</DataFetcher>Render Props vs HOCs
- Render Props: More flexible, easier to test, explicit dependencies
- HOCs: More declarative, can be composed, less verbose
- Use Render Props for: Complex state logic, dynamic behavior
- Use HOCs for: Cross-cutting concerns, simple enhancements
- Both patterns can be used together effectively
Common Render Props Examples
Example
// Toggle render prop
const Toggle = ({ children }) => {
const [isOn, setIsOn] = useState(false);
const toggle = () => setIsOn(!isOn);
return children({ isOn, toggle });
};
// Form render prop
const Form = ({ children, onSubmit }) => {
const [values, setValues] = useState({});
const [errors, setErrors] = useState({});
const handleChange = (name, value) => {
setValues(prev => ({ ...prev, [name]: value }));
setErrors(prev => ({ ...prev, [name]: '' }));
};
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(values);
};
return children({
values,
errors,
handleChange,
handleSubmit
});
};Mini-Project: Modal Render Prop
Example
// Complete modal render prop implementation
import React, { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';
const Modal = ({ isOpen, onClose, children }) => {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
return () => setMounted(false);
}, []);
useEffect(() => {
if (isOpen) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'unset';
}
return () => {
document.body.style.overflow = 'unset';
};
}, [isOpen]);
if (!mounted || !isOpen) return null;
return createPortal(
<div className="modal-overlay" onClick={onClose}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
{children}
</div>
</div>,
document.body
);
};
const ModalProvider = ({ children }) => {
const [isOpen, setIsOpen] = useState(false);
const [modalContent, setModalContent] = useState(null);
const openModal = (content) => {
setModalContent(content);
setIsOpen(true);
};
const closeModal = () => {
setIsOpen(false);
setModalContent(null);
};
return (
<>
{children({ openModal, closeModal })}
<Modal isOpen={isOpen} onClose={closeModal}>
{modalContent}
</Modal>
</>
);
};
// Usage
<ModalProvider>
{({ openModal, closeModal }) => (
<div>
<button onClick={() => openModal(<div>Modal Content</div>)}>
Open Modal
</button>
</div>
)}
</ModalProvider>