Skip to content

Instantly share code, notes, and snippets.

@brigand
Last active April 18, 2017 00:03
Show Gist options
  • Save brigand/b709cba99bb820fae4209fc53097d5bf to your computer and use it in GitHub Desktop.
Save brigand/b709cba99bb820fae4209fc53097d5bf to your computer and use it in GitHub Desktop.
React DI provider, proof of concept
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} />;
}
}
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