React Render Props

By

Learn the render props pattern in React, passing a function as a prop, often children, so a component can share its state with the components it renders.

~~~

Note: render props still work in React 19, but today hooks are the usual way to share stateful logic between function components. The examples below use class components, as they did when I wrote this post, and mount the app with createRoot, since ReactDOM.render was removed in React 19.

A common pattern used to share state between components is to use the children prop.

Inside a component JSX you can render {this.props.children} which automatically injects any JSX passed in the parent component as a children:

class Parent extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      /*...*/
    }
  }

  render() {
    return <div>{this.props.children}</div>
  }
}

const Children1 = () => {}

const Children2 = () => {}

const App = () => (
  <Parent>
    <Children1 />
    <Children2 />
  </Parent>
)

However, there is a problem here: the state of the parent component cannot be accessed from the children.

To be able to share the state, you need to use a render prop component, and instead of passing components as children of the parent component, you pass a function which you then execute in {this.props.children()}. The function can accept arguments:

class Parent extends React.Component {
  constructor(props) {
    super(props)
    this.state = { name: 'Flavio' }
  }

  render() {
    return <div>{this.props.children(this.state.name)}</div>
  }
}

const Children1 = props => {
  return <p>{props.name}</p>
}

const App = () => <Parent>{name => <Children1 name={name} />}</Parent>

Instead of using the children prop, which has a very specific meaning, you can use any prop, and so you can use this pattern multiple times on the same component:

import React from 'react'
import { createRoot } from 'react-dom/client'

class Parent extends React.Component {
  constructor(props) {
    super(props)
    this.state = { name: 'Flavio', age: 35 }
  }

  render() {
    return (
      <div>
        <p>Test</p>
        {this.props.someprop1(this.state.name)}
        {this.props.someprop2(this.state.age)}
      </div>
    )
  }
}

const Children1 = props => {
  return <p>{props.name}</p>
}

const Children2 = props => {
  return <p>{props.age}</p>
}

const App = () => (
  <Parent
    someprop1={name => <Children1 name={name} />}
    someprop2={age => <Children2 age={age} />}
  />
)

const root = createRoot(document.getElementById('app'))
root.render(<App />)
Tagged: React · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about react: