Last active
April 18, 2017 00:03
-
-
Save brigand/b709cba99bb820fae4209fc53097d5bf to your computer and use it in GitHub Desktop.
React DI provider, proof of concept
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class DIProvider extends React.Component { | |
static childContextTypes = { | |
injector: PropTypes.func, | |
}; | |
getChildContext() { | |
return {injector: this.props.injector}; | |
} | |
render() { | |
return this.props.children; | |
} | |
} | |
export const makeInjector() { | |
const x = new Map(); | |
const pubsub = new EventEmitter(); | |
const set = (key, value) => { | |
x.set(key, value); | |
events.emit('update'); | |
}; | |
const get = (key) => { | |
x.get(key); | |
}; | |
const subscribe = (fn) => { | |
events.on('update', fn); | |
// unsubscribe | |
return () => events.off('update', fn); | |
}; | |
return {set, get, subscribe}; | |
} | |
export const withInjector = (C) => class WithInjector extends React.Component { | |
static contextTypes = { | |
injector: PropTypes.object.isRequired, | |
}; | |
constructor(props) { | |
super(props); | |
this.state = {}; | |
} | |
componentDidMount() { | |
this.unsub = this.context.injector.subscribe(() => { | |
// force an update | |
this.setState({x: Math.random()}); | |
}); | |
} | |
componentWillUnmount() { | |
this.unsub(); | |
} | |
render() { | |
const {injector} = this.context; | |
return <C {...this.props} diGet={injector.get} diSet={injector.set} />; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const injector = makeInjector(); | |
injector.set('name', 'John Doe'); | |
ReactDOM.render( | |
<DIProvider injector={injector}> | |
<App />{/* or redux Provider or react-router Router, etc */} | |
</DIProvider> | |
, el); | |
const App = withInjector(({diGet}) => { | |
return <div>Hello, {diGet('name')}</div>; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment