ReviseAlgo Logo

Advanced React

Render Props

Master React Render Props, covering stateful logic sharing, render function signatures, children as render props, and Custom Hooks comparison.

Last Updated: July 15, 2026 12 min read

1. Learning Objectives

In this lesson, you will learn how to share component logic using render functions. By the end of this topic, you will be able to:

  • Explain the core concept of the Render Props design pattern.
  • Share stateful logic by passing functions as props.
  • Implement render props using the implicit children prop function signature.
  • Identify performance issues like garbage collection overhead caused by inline render functions.
  • Differentiate scenarios where Render Props are preferred over Custom Hooks.

2. Overview

The **Render Props** pattern is a React design pattern where a component receives a function that returns a React element as a prop, and calls this function to render its content. This pattern makes it easy to share stateful logic (like tracking mouse coordinates or checking scroll position) without hardcoding how that state is displayed.

3. Why This Topic Matters

Render Props separate logic from presentation, helping you write clean, reusable code:

  • Separation of Concerns: You can package complex stateful logic (like subscription management or viewport tracking) into a single reusable component, leaving the visual presentation completely customizable by the consumer.
  • Dynamic Layout Injection: Render props allow the parent component to pass dynamic values (like cursor positions or API states) directly into customizable layout templates.

4. Real-World Analogy

Think of the Render Props pattern like **renting a self-service photo booth**:

  • Monolithic Component: A photo booth that only prints photos in a single predefined black-and-white grid format. You cannot customize the background or layout.
  • Render Props Component: A photo booth that captures the image data (tracks the state: coordinates, images) and then passes that raw data to a callback printer function (the render prop). You can tell the printer to display the image as a postcard, a passport photo, or a digital poster. The booth handles the photo capture logic, and you control the presentation.

5. Core Concepts

Below is a comparison of Render Props and Custom Hooks:

Property Render Props Pattern Custom Hooks Pattern
Boilerplate / Nesting Can lead to nested JSX elements ("wrapper hell") if combining multiple providers. Clean and flat component structure; hooks are called directly in the component.
Component Composition High composition flexibility; can wrap specific areas of the render tree. Applies to the entire component scope.
Performance profile Defining render functions inline creates a new function reference on every render, increasing garbage collection. No function creation overhead in JSX.

6. Syntax & API Reference

This example shows how to write a coordinate tracker component using a render prop:

7. Visual Diagram

This diagram displays how state values flow from logic components to render templates:

8. Live Example — Full Working Code

Below is a complete HTML page demonstrating a mouse coordinate tracker built using the Render Props pattern:

What just happened? The MouseTracker component handles the mouse listener events and calculations internally. It then calls the render prop function, passing the current coordinates. This lets us use the same tracking logic for two different UI presentations: displaying raw text in the first container and rendering a custom red dot in the second.

9. Interactive Playground

Try It Yourself Challenges:

  1. Change the coordinates offset so that the custom dot marker is centered exactly under the cursor.
  2. Build a ViewportTracker component that tracks page scroll offsets, and use a render prop to display a scroll-to-top button only when the user scrolls down.

10. Common Mistakes

Mistake Why it happens Wrong Correct
Defining render prop functions inline inside React.memo components Defining a render prop function inline in JSX (e.g. render={val => <Comp val={val} />}) creates a new function reference on every render, bypassing any performance optimizations from React.memo. Declaring inline render functions inside performance-critical components. Define the render function as an instance method or a static, cached reference to preserve reference equality.
Confusing children render functions with standard children elements If you configure a component to expect a function as the children prop, passing static JSX children instead of a function will throw a rendering error. <MouseTracker><p>Static text</p></MouseTracker> (crashes since child is not a function) <MouseTracker>{coords => <p>X: {coords.x}</p>}</MouseTracker>

11. Best Practices

  • Prefer Children as Render Props: Use the children prop function signature (e.g. <Comp>{data => ...}</Comp>) to make the code cleaner and more readable.
  • Avoid Inline Functions for Heavy Renders: For performance-critical components, define the render function as an instance method or use a cached reference to avoid recreating it on every render.
  • Verify function signatures: Always verify that the render prop is a function (e.g. typeof render === 'function') before calling it.

12. Browser Compatibility/Requirements

The Render Props pattern is supported in all browsers that run React.

13. Interview Questions

Q1: What is the Render Props design pattern? Explain how it shares stateful logic.

Answer: The Render Props pattern is a design pattern where a component receives a function that returns a React element as a prop. The component manages the stateful logic internally (e.g., coordinates, scrolling, fetching state) and then calls this function, passing the state as arguments. This allows the consumer to decide exactly how that state is displayed.

Q2: How do Custom Hooks compare to Render Props? When would you still use Render Props?

Answer: While Custom Hooks have largely replaced Render Props because they avoid nested JSX elements ("wrapper hell"), Render Props are still useful when: (1) wrapping specific parts of a layout rather than the entire component scope, or (2) sharing dynamic layout structures where child rendering must be configured directly within JSX templates.

14. Debugging Exercise

Identify why this component crashes, throwing "render is not a function" errors in the browser:

View Solution

Diagnosis: The DataProvider component calls the render function, but the consumer does not pass a render prop, causing it to evaluate as undefined. We should add a safety check or a default fallback rendering behavior:

15. Practice Exercises

Exercise 1: Create a viewport width tracker

Build a component named ViewportWidth. Track the browser's window width inside this component, and use a render prop to display different layouts (e.g. mobile vs desktop) based on the current width.

16. Scenario-Based Challenge

The Multi-source real-time metrics feed dashboard card:

You are designing a dashboard where cards subscribe to different real-time web socket data feeds. The layout of the cards varies (some display line charts, others display raw metric cards or tables). Describe how you would implement a compound SubscriptionProvider that uses a render prop to inject real-time socket data into custom dashboard cards.

17. Quick Quiz

Q1: What does an inline render prop function do to component re-renders?

A) It has no effect on rendering performance.

B) It creates a new function reference on every render, which can bypass memoization optimizations.

C) It caches component outputs automatically.

Answer: B — Defining render prop functions inline in JSX creates a new function reference on every render, bypassing any performance optimizations from React.memo.

18. Summary & Key Takeaways

  • The Render Props pattern passes functions as props to share stateful logic.
  • This pattern separates logic from presentation.
  • You can use the children prop function signature for cleaner code.
  • Avoid defining render functions inline in performance-critical components.

19. Cheat Sheet

Render Prop Pattern Element Description
<Provider render={val => <Comp val={val} />} /> Passes the render function as a prop named render.
<Provider>{val => <Comp val={val} />}</Provider> Passes the render function implicitly as the children prop.
{this.props.children(this.state)} Calls the children render function inside the provider, passing state data.
---