esnextb.in
import React, { PropTypes as t } from 'react'
var inject = (selector = pass => pass ) =>
connect(
({ pass }) => selector(pass),
{ pass: t.object }
)
var Context = Object.assign(
({ children, ...props }, { pass = {} }) =>
<Provider
pass={{ ...pass, ...props }}
contextTypes={{ pass: t.object }}>
<children.type {...props} {...children.props} />
</Provider>
, { pass: t.object }
)
import { observable } from 'mobservable'
var model = Object.assign(observable([]), {
add(item) {
this.push(item)
}
})
var View = ({ store }) =>
<div>
{ store.map(item =>
<div>{ item }</div>
)}
<button onClick={e =>
store.add(Math.random())
}>ADD</button>
</div>
import { observer } from 'mobservable-react'
View =
inject()(observer (View)
)
export default props =>
<Context store={ model }>
<View/>
</Context>
// my DI library
function Provider ({ contextTypes, children, ...context }) {
var Container = React.createClass({
childContextTypes: contextTypes,
getChildContext() { return context },
render() { return this.props.children } // expect single child
})
return <Container>{ children }</Container>
}
function connect(selector, contextTypes) {
if(typeof selector != 'function') {
contextTypes = selector
return connect(context => context, contextTypes)
}
return Component => Object.assign(
(props, context) => // props supersede context, easier to test
<Component { ...selector(context) } { ...props }/>
, { contextTypes }
)
}