Skip to main content
Course/Module 10/Topic 2 of 4Advanced

Advanced Render Props

Learn the Render Props pattern to share code between components using a function as a child pattern.

90 minBy Priygop TeamLast 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>

Additional Resources

Recommended Reading

  • React Advanced Patterns Guide
  • Higher-Order Components Documentation
  • Render Props Pattern Guide
  • Compound Components Best Practices

Online Resources

  • Advanced React Patterns Tutorial
  • React Component Composition
  • Reusable Component Design
  • React Performance Patterns
Chat on WhatsApp
Priygop - Leading Professional Development Platform | Expert Courses & Interview Prep