Skip to content

render-prop helper to render anything (Functions, Components, Elements, ...)

License

Notifications You must be signed in to change notification settings

sastan/react-render-callback

Repository files navigation

react-render-callback

render anything (Function as Child, Render Props, Components, Elements, ...)


version MIT License module formats: umd, cjs, and es umd size umd gzip size

Build Status Code Coverage Maintainability PRs Welcome Code of Conduct

Sponsored by Kenoxa Semver semantic-release Greenkeeper badge

The problem

You want your component to support the render prop pattern and you want to support several different types of values like Function as children, a React.Component or just plain react elements.

This solution

react-render-callback frees you from detecting what kind of callback your component is dealing with:

import React from 'react'

import render from 'react-render-callback'

class Component from React.Component {
  state = {}

  render() {
    // can be any prop: return render(this.props.renderHeader, this.state.header)
    return render(this.props.children, this.state)
  }
}

View an example live in codesandbox.io.

Table of Contents

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's dependencies:

npm install --save react-render-callback

This package also depends on react. Please make sure you have it installed as well.

Usage

API

render([ renderable [, props [, options ] ] ]):

  • renderable (optional): anything that can be rendered like a function, a component, or elements

  • props (optional): to pass to renderable (if renderable is a function or react element type)

  • options (optional):

    • cloneElement (optional, default: false): allows to pass props to the element using React.cloneElement

      render(<a href="#bar">bar</a>, {title: 'foo'})
      // --> <a href="#bar">bar</a>
      
      render(<a href="#bar">bar</a>, {title: 'foo'}, {cloneElement: true})
      // --> <a href="#bar" title="foo">bar</a>

returns

  • null for false, null, undefined, NaN and an empty string
  • the value as is for all other values

Example

import React from 'react'

import render from 'react-render-callback'

class Component from React.Component {
  state = {
    to: 'pass down'
  }

  render() {
    // can be any prop: return render(this.props.renderHeader, this.state.header)
    return render(this.props.render || this.props.children, this.state)
  }
}

const functionComponent = (props) => <span>{props.to}</span>

class ClassComponent from React.Component {
  render() {
    return <span>{this.props.to}</span>
  }
}

const App = () => (
  <dl>
    <dt>render prop</dt>
    <dd><Component render={functionComponent} /></dd>

    <dt>function as a child</dt>
    <dd><Component>{functionComponent}</Component></dd>

    <dt>render Component</dt>
    <dd><Component render={ClassComponent} /></dd>

    <dt>component as child</dt>
    <dd><Component>{ClassComponent}</Component></dd>

    <dt>plain childs - nothing to pass down - maybe just doing some lifecycle stuff</dt>
    <dd><Component><strong>Plain</strong> childs</Component></dd>
  </dl>
)

Other Solutions

Credits

A special thanks needs to go to Kent C. Dodds for his great video series ( egghead.io, frontendmasters.com and youtube.com). His projects are either used in this project (kcd-scripts) or are a template for the structure of this project (downshift). Make sure to subscribe to his newsletter.

Contributors

Thanks goes to these people (emoji key):


Sascha Tandel
πŸ’» πŸ“– πŸš‡ ⚠️ πŸ‘€ πŸ“ πŸ› πŸ’‘ πŸ€” πŸ“’

This project follows the all-contributors specification. Contributions of any kind welcome!

LICENSE

MIT