render-prop helper to render anything (Functions, Components, Elements, ...)
You want your component to support the render proppattern
with different types of values like
Function as children,
a React.Component (Component Injection)
or just plain react elements.
react-render-callback frees you from detecting what kind fo render prop
your component is dealing with:
importReactfrom'react'importrenderCallbackfrom'react-render-callback'classComponentfromReact.Component{state={}render(){// can be any prop like render, component, renderHeader, ...// children may be a function, a component, an element, ...returnrenderCallback(this.props.children,this.state)}}View an example in codesandbox.io.
- 📦 Super tiny (~650 bytes)
- 👌 Dependency free (except for Object.assign polyfill)
- 🔌 Just Works TM
- 🔮 Tree shaking friendly (ESM, no side effects)
- 📚 Well documented
- 💯 test coverage
- ☀️ supports React v0.14, v15 and v16
- 👪 supports rendering of
- Stateless Function Components (SFC)
with one argument (the common
propscase) aka Render Props aka Function as Child or optional with several arguments - Class Components aka Component Injection
- Context Provider and Consumer
- Forward Refs
- Factories
- Elements with optional support for cloning to merge props
- primitives like strings, numbers, arrays, ...
false,null,undefinedandtrueare returned asnulljust like in JSX
- Stateless Function Components (SFC)
with one argument (the common
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-callbackThis package also depends on
react. Please make sure you have it installed as well.
The Universal Module Definition (UMD) is available
via unpkg.com and exposed as ReactRenderCallback.
<scriptsrc="https://unpkg.com/react-render-callback/dist/react-render-callback.umd.min.js"></script>renders the given
renderablewithprops
// esmimportrenderCallbackfrom'react-render-callback'// commonjsconstrenderCallback=require('react-render-callback')renderable (optional): anything that can be rendered like a function, a component, or elements
- uses
React.createElementfor react types like class components, context provider or consumer, forward refs, factories, ... - invokes stateless function components (SFC) respecting their
defaultProps- not using
React.createElementfor improved performance - except the SFC has
propTypesandprocess.env.NODE_ENVis notproduction, in that caseReact.createElementis used to enable typechecking with PropTypes
- not using
- gracefully handles other types like string, array, react elements, ...
props (optional): to pass to renderable
options (optional):
cloneElement(default:false, since: v1.1.0): allows to passpropsto the element usingReact.cloneElement
renderCallback(<ahref="#bar">bar</a>,{title: 'foo'})// --> <a href="#bar">bar</a>renderCallback(<ahref="#bar">bar</a>,{title: 'foo'},{cloneElement: true})// --> <a href="#bar" title="foo">bar</a>returns
- the created react element
false,null,undefinedandtrueare returned asnulljust like in JSX- the value as is for all other values
since: v1.1.0
Returns a function (
(...args) => ...) to renderrenderablewith.
// esmimport{createRender}from'react-render-callback'// commonjsconst{createRender}=require('react-render-callback')Accepts the same arguments (except props) as renderCallback(). It exists mainly
to pre-determine (read cache) what type renderable is, to prevent these
checks on every invocation.
Additionally the returned method accepts more than one argument (since: v1.2.0).
This allows to provide several parameters to the renderable.
constrenderCallback=createRender((a,b,c)=>({a, b, c}))renderCallback(1,2,3)// -> { a: 1, b: 2, c: 3 }If the
renderablehas adefaultPropsproperty only the first parameter is used and merged with thedefaultProps.
returns
a function ((...args) => ...) to render the args
A basic example showing the most common use cases can be viewed/edited at codesandbox.io.
This option allows to pass down
propswithout to need to create a function within render which merges the defined and provided props.
classCountSecondsextendsReact.Component{state={value: 0,}componentDidMount(){this.timer=setInterval(()=>{this.setState(({value})=>({value: value+1}))},1000)}componentWillUnmount(){clearInterval(this.timer)}render(){const{children, render =children}=this.propsreturnrenderCallback(render,this.state,{cloneElement: true})}}constDisplayValue=({prefix ='', value})=>`${prefix}${value}`constApp=({prefix})=>(<CountSeconds><DisplayValueprefix={prefix}/></CountSeconds>)classCountSecondsextendsReact.Component{state={value: 0,}reset=()=>{this.setState({value: 0})}componentDidMount(){this.timer=setInterval(()=>{this.setState(({value})=>({value: value+1}))},1000)}componentWillUnmount(){clearInterval(this.timer)}render(){const{children, render =children}=this.propsreturncreateRender(render)(this.state.value,this.reset)}}constDisplayValue=({prefix ='', value})=>`${prefix}${value}`constApp=()=>(<CountSeconds>{(value,reset)=>(<React.Fragment><DisplayValueprefix="Seconds: "value={value}/><buttononClick={reset}type="button">
reset
</button></React.Fragment>)}</CountSeconds>)importTogglefrom'react-toggled'classTogglerextendsReact.Component{staticdefaultProps={onLabel: 'Toggled On',offLabel: 'Toggled Off',}render(){const{on, getTogglerProps, onLabel, offLabel}=this.propsreturn(<div><button{...getTogglerProps()}>Toggle me</button><div>{on ? onLabel : offLabel}</div></div>)}}constToggleView=createRender(Toggler)constApp=()=><Toggle>{ToggleView}</Toggle>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.
Thanks goes to these people (emoji key):
Sascha Tandel 💻📖🚇 |
|---|
This project follows the all-contributors specification. Contributions of any kind welcome!
MIT