DEV Community

Cover image for Render Props Pattern in React
Md Enayetur Rahman
Md Enayetur Rahman

Posted on

Render Props Pattern in React

A Patterns.dev perspective + real‑world examples

“A render prop is a prop whose value is a function that returns JSX.”

The render props pattern lets components share logic by delegating what to render to a function supplied by their parent. This article summarises Lydia Hallie & Addy Osmani’s take in Learning Patterns and shows how to apply it in practice.


1  Why Render Props?

Higher‑Order Components (HOCs) once ruled the reusability roost, but they introduce naming collisions and “invisible” props. Render props solve this by explicitly passing data through a function parameter, avoiding prop clashes and clarifying where data comes from.

TL;DR benefits

Benefit Why it matters
Explicit data flow The arguments list shows exactly what’s provided
No prop name collisions You choose argument names, not the HOC
Easy logic/markup separation State lives in the wrapper, UI lives in the function

2  A Mini Example

// <Title> renders whatever its caller returns
const Title = ({ render }) => render();

// Usage
<Title render={() => <h1>✨ I am a render prop! ✨</h1>} />
Enter fullscreen mode Exit fullscreen mode

Because Title delegates its output, you can reuse it with totally different UI every time.


3  Passing Data Down

A render‑prop component usually provides data as an argument:

function Component({ render }) {
  const data = { loggedIn: true };
  return render(data);
}

<Component render={({ loggedIn }) => <Status ok={loggedIn} />} />
Enter fullscreen mode Exit fullscreen mode

Now the consumer decides how to render based on data.

4  Temperature Converter Demo

Below is the refactor straight from the book:

function Input(props) {
  const [value, setValue] = useState("");
  return (
    <>
      <input value={value} onChange={e => setValue(e.target.value)} />
      {props.render(value)}
    </>
  );
}

export default function App() {
  return (
    <Input render={value => (
      <>
        <Kelvin value={value} />
        <Fahrenheit value={value} />
      </>
    )}/>
  );
}
Enter fullscreen mode Exit fullscreen mode

Kelvin and Fahrenheit gain access to the user’s input without lifting state all the way up the tree.


5  Children‑as‑a‑Function Variant

Instead of a dedicated render prop, you can pass the function as the child:

<Input>
  {value => (
    <>
      <Kelvin value={value} />
      <Fahrenheit value={value} />
    </>
  )}
</Input>
Enter fullscreen mode Exit fullscreen mode

Under the hood you invoke props.children(value). Same pattern, different syntax.


6  5+ Real‑World Use Cases

Library / Component What the render prop does Why it’s handy
React Router <Route> Supplies match, history, location objects so you can decide what to render for a URL. Avoids wrapping components with HOCs just for routing context.
Formik <Formik> Gives values, errors, touched, and helpers like setFieldValue. Lets you build custom forms without being locked into <Field> markup.
Downshift <Downshift> Provides state & helpers (getInputProps, isOpen, highlightedIndex) for accessible dropdowns. Separates autocomplete logic from UI, so you can render any dropdown design.
React‑Spring <Spring> / <Transition> Passes animated style values into your render function every frame. You choose the element; the library handles physics & interpolation.
React‑Motion <Motion> Similar to React‑Spring; delivers interpolated styles so you can animate anything. Keeps animation logic out of component body.
Apollo Client <Query> / <Mutation> (pre‑hooks) Supplies loading, data, error, and functions like mutate. Collocates GraphQL data with the UI that needs it—without nesting providers.

These libraries leveraged render props to expose powerful behaviour through a tiny API surface long before hooks existed.


7  Pros & Cons According to the Book

✅ Pros

  • Clear, explicit props – no hidden merges.
  • Easy to share logic & data across multiple components.
  • Keeps stateful logic separate from stateless presentation.

⚠️ Cons

  • Deeply nested trees if you stack many render‑prop components.
  • Largely superseded by Hooks (e.g., useQuery, useSpring).

8  When Should You Still Use It?

  • You need to expose multiple pieces of stateful data to arbitrary markup.
  • You’re supporting projects stuck on React < 16.8 (no hooks).
  • You want library consumers to decide how to render but reuse what to render logic.

9  Key Take‑aways

  1. A render prop is just “a function that returns JSX.”
  2. It’s perfect for state/logic → view separation.
  3. Hooks may replace it in many cases, but render props are still a valuable tool in your pattern toolbox.

Feel free to copy the snippets above, fork the Codesandboxes in the original chapter, and experiment!


Content adapted from “Render Props Pattern,” Patterns.dev (CC BY‑NC 4.0).

Top comments (0)