@macklinu/render-props
v1.0.1
Published
A helper function to support various React render prop use cases
Downloads
176
Readme
@macklinu/render-props
A helper function to support various React render prop use cases
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
: Theprops
object from a React componentnewProps
: The props object passed into the render prop function (component
,render
, orchildren
), 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!