React components and decorators for putting context-like values into context and pulling them out as props
Heavily copied/modeled off the code used in react-redux by @gaearon
npm install --save react-tunnel
.
for React: require/import from react-tunnel
.
For React Native: require/import from react-tunnel/native
.
react-tunnel
helps you provide injectable props to child components to help avoid deep chains of prop passing
- install with
npm install react-tunnel
- import or require
Provider
andinject
by
//es5
var Provider = require('react-tunnel').Provider;
var inject = require('react-tunnel').inject;
//es6
import { Provider, inject } from 'react-tunnel'
- wrap a
Component
tree with<Provider provide={fn|object}>
like
//using object provide
render() {
return (
<Provider provide={{thing: "one", anotherThing: 2}}>
<Anything>
</Provider>
)
}
//or as a function
function provider () {
return {
thing: "one",
anotherThing: 2g
}
}
render() {
return (
<Provider provide={provider}>
<Anything>
</Provider>
)
}
- decorate a child component with
inject
and provide a mapping function determine which provided props to inject into the decorated component
var SomeChild = require('./SomeChildOfAnything') //a react Component
function mapProvidedToProps(provided) {
return {
that: provided.thing
}
}
//notice that inject returns a wrapping function
var InjectedChild = inject(mapProvidedToProps)(SomeChild);
// now in InjectedChild props will have `that`
...
render() {
var injectedProp = this.props.that;
return <span>{injectedProp}</span>;
//will render as <span>one</span>
}
react-tunnel
uses React's context feature to make provided props available to children regardless of how deep they are. While this is powerful it also can be abused and make for a nightmare to manage.
It is reccommended that this functionality be used to provide generally static properties that don't change much if at all based on the local conditions of the injecting component. Examples might include
- Providing viewport dimensions to arbitrarily deep Components
- Providing redux action creators from a parent
connected
Component to deep children
Also please consider that the context api for React has PropType checking for a reason and that by using this library and opting out of that stronger contract has costs and you may want to utilize the base context features rather than this library
makes provide
available via context.provided
to children of Provider. use inject
to access them easily
provide {fn | object}
:provide: function(parentProvided) { return provided{object} }
: will provide the return value ofprovide
prop. Function takes in any provided values from parent providers if any. If none, an empty object is passed.provide: object
: provides any parent provided values if nested along withprovide
object properties. if there is a key collision the properties of theprovide
prop are used and mask similarly named properties from any parent provided objects
Provider
s are nestable and if using the object version of provide
will automatically reprovide any values provided in the immediate parent Provider
. Use this if you want to say Provide some truly global props at the root of your App but also use Provider
s for Redux action creators produced via connect
to the local render tree.
If you nest Provider
s but use the function form of provide
you will need to forward any desired parent provided values using the function forms argument parentProvided
.
Creates a decorator which injects props from Provider
into the decorated component according to the mapProvidedToProps
function.
mapProvidedToProps(provided)? returns object
: called when decorated Component mounts and when it receives new context. the return object of this call is added to the underlying Component as propsdefault
: ifmapProvidedToProps
is not passed toinject
then allProvider
values are passed to underlying component.
- @gaearon for inspiring this API with the more specialized react-redux
- @rt2zz for helping flesh out the design and API
MIT