0.1.19 • Published 5 years ago

@render-props/compose v0.1.19

Weekly downloads
1
License
MIT
Repository
github
Last release
5 years ago

compose ()

A utility for flattening nested render props (function as child) component calls safely and in a way that doesn't take a huge performance hit.

Installation

yarn add @render-props/compose or npm i @render-props/compose


compose(Components <object {propName: Component}>)

// the order is important because render props from Toggle will only
// be available in a Counter prop callback if Toggle is defined before
// Counter in the composition
const Composed = compose({
  toggle: Toggle,  // cannot receive render props from Counter
  counter: Counter // can receive render props from Toggle
})

// Plain objects as props
<Composed toggle={propsPassedToToggle} counter={propsPassedToCounter}>
  {function ({toggle, counter}) {
    // toggle = render props returned by the Toggle component
    // counter = render props returned by the Counter component
  }}
</Composed>

// Function as props
<Composed
  toggle={propsPassedToToggle/*plain object*/}
  counter={
    ({toggle/*render props returned by Toggle component*/}) => ({
      initialValue: toggle.value ? 0 : 1,
      ...otherCounterProps
    })
  }
>
  {function ({toggle, counter}) {
    // toggle = render props returned by the Toggle component
    // counter = render props returned by the Counter component
  }}
</Composed>

Usage

import compose from '@render-props/compose'
import Toggle from '@render-props/toggle'
import Counter from '@render-props/counter'


const ToggleCounter = compose({toggle: Toggle, counter: Counter})

function SomeComponent (props) {
  /**
  This is the same as:

  function SomeComponent (props) {
    <Toggle initialValue={true}>
      {function (toggleContext) {
        return (
          <Counter initialValue={toggleContext.value ? 6 : 0} initialStep={4}>
            {function (counterContext) {
              const derivedProps = {
                toggle: toggleContext,
                counter: counterContext
              }

              return (
                ...
              )
            }}
          </Counter>
        )
      }}
    </Toggle>
  }
  **/
  return (
    <ToggleCounter
      toggle={{initialValue: true}}
      counter={({toggle}) => ({initialValue: toggle.value ? 6 : 0, initialStep: 4})}
    >
      {({toggle, counter}) => (
        <div>
          <div>
            Toggle value: {JSON.stringify(toggle.value)}

            <button onClick={toggle.toggle}>
              Toggle me to {toggle.value === true ? 'false' : 'true'}
            </button>
          </div>

          <div>
            Counter value: {counter.value}

            <button onClick={counter.incr}>
              incr() me by {counter.step}
            </button>

            <button onClick={counter.decr}>
              decr() me by {counter.step}
            </button>
          </div>
        </div>
      )}
    </ToggleCounter>
  )
}
0.1.19

5 years ago

0.1.18

5 years ago

0.1.17

5 years ago

0.1.16

5 years ago

0.1.15

6 years ago

0.1.14

6 years ago

0.1.13

6 years ago

0.1.12

6 years ago

0.1.11

6 years ago

0.1.10

6 years ago

0.1.9

6 years ago

0.1.8

6 years ago

0.1.7

6 years ago

0.1.6

6 years ago

0.1.5

6 years ago

0.1.4

6 years ago

0.1.3

6 years ago

0.1.2

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago