@macklinu/render-props
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.1 • Public • Published

    @macklinu/render-props

    A helper function to support various React render prop use cases

    npm Build Status license code style: prettier semantic-release All Contributors

    Motivation

    If you're building React components using render props, this library aims to simplify various render prop use cases.

    Installation

    npm install @macklinu/render-props
    

    Example

    See this CodeSandbox for an in-browser example.

    See src/types/example.tsx for a TypeScript example and using the provided TypeScript types.

    Usage

    Let's build a Counter component using a traditional render prop.

    import React from 'react'
     
    class Counter extends React.Component {
      state = { count: 0 }
     
      render() {
        return this.props.render({
          count: this.state.count,
          increment: this.increment,
          decrement: this.decrement,
        })
      }
     
      increment = () => {
        this.setState(prevState => ({ count: prevState.count + 1 }))
      }
     
      decrement = () => {
        this.setState(prevState => ({ count: prevState.count - 1 }))
      }
    }

    This works well if you only support a render prop function:

    <Counter
      render={props => (
        <div>
          <span>{props.count}</span>
          <button onClick={props.decrement}>-</button>
          <button onClick={props.increment}>+</button>
        </div>
      )}
    />

    But what if you want to use a prop other than render? For example, a children function prop is popular alternative to render:

    <Counter>
      {props => (
        <div>
          <span>{props.count}</span>
          <button onClick={props.decrement}>-</button>
          <button onClick={props.increment}>+</button>
        </div>
      )}
    </Counter>

    This is where @macklinu/render-props comes into play. It allows render props named component, render, and children (in that order), making it simpler for your React components to support common render prop APIs.

    import React from 'react'
    import renderProps from '@macklinu/render-props'
     
    class Counter extends React.Component {
      state = { count: 0 }
     
      render() {
        return renderProps(this.props, {
          count: this.state.count,
          increment: this.increment,
          decrement: this.decrement,
        })
      }
     
      increment = () => {
        this.setState(prevState => ({ count: prevState.count + 1 }))
      }
     
      decrement = () => {
        this.setState(prevState => ({ count: prevState.count - 1 }))
      }
    }

    And now you can use all cases:

    <div>
      <Counter
        component={props => (
          <div>
            <h2>
              Using the <code>component</code> prop
            </h2>
            <span>{props.count}</span>
            <button onClick={props.decrement}>-</button>
            <button onClick={props.increment}>+</button>
          </div>
        )}
      />
      <Counter
        render={props => (
          <div>
            <h2>
              Using the <code>render</code> prop
            </h2>
            <span>{props.count}</span>
            <button onClick={props.decrement}>-</button>
            <button onClick={props.increment}>+</button>
          </div>
        )}
      />
      <Counter>
        {props => (
          <div>
            <h2>
              Using the <code>children</code> prop
            </h2>
            <span>{props.count}</span>
            <button onClick={props.decrement}>-</button>
            <button onClick={props.increment}>+</button>
          </div>
        )}
      </Counter>
    </div>

    API Reference

    renderProps(props: Object, newProps: Object): ReactElement

    • props: The props object from a React component
    • newProps: The props object passed into the render prop function (component, render, or children), which can be used by consumer components for rendering a React element.

    Returns the React element returned from the component, render, or children prop. If none of those props are provided, returns null.

    Contributors

    Thanks goes to these wonderful people (emoji key):


    Macklin Underdown

    💻 📖 ⚠️

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

    Install

    npm i @macklinu/render-props

    DownloadsWeekly Downloads

    71

    Version

    1.0.1

    License

    MIT

    Last publish

    Collaborators

    • avatar