Last active
December 21, 2015 16:35
-
-
Save tgriesser/d5d80ade6f895c28e659 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import {Component} from 'react' | |
import shallowEqual from 'react/lib/shallowEqual' | |
export function observe(ComposedComponent) { | |
if (!ComposedComponent.observe) { | |
return ComposedComponent | |
} | |
Object.defineProperty(ComposedComponent.prototype, 'data', { | |
get: function() { | |
return this.props.data | |
} | |
}) | |
const Enhancer = class extends Component { | |
constructor(props, context) { | |
super(props, context) | |
this.subscriptions = {} | |
this.state = {} | |
this.resubscribe(props, context) | |
} | |
shouldComponentUpdate(nextProps, nextState, nextContext) { | |
return ( | |
!shallowEqual(this.props, nextProps) || | |
!shallowEqual(this.state, nextState) || | |
!shallowEqual(this.context, nextContext) | |
) | |
} | |
componentWillReceiveProps(props, context) { | |
this.resubscribe(props, context) | |
} | |
componentWillUnmount() { | |
this.unsubscribe() | |
} | |
resubscribe(props, context) { | |
const newObservables = ComposedComponent.observe(props, context) | |
const newSubscriptions = {} | |
Object.keys(newObservables).forEach((key) => { | |
let value = newObservables[key] | |
if (typeof value.subscribe !== 'function') { | |
throw new Error(`Must observe observables, ${key} is not observable`) | |
} | |
newSubscriptions[key] = value.subscribe({ | |
next: (val) => { | |
if (this.state.hasOwnProperty(key)) { | |
this.setState({[key]: val}) | |
} else { | |
this.state[key] = val | |
} | |
}, | |
throw: () => {}, | |
return: () => {} | |
}) | |
if (!this.state.hasOwnProperty(key)) { | |
this.state[key] = null | |
} | |
}) | |
this.unsubscribe() | |
this.subscriptions = newSubscriptions | |
} | |
unsubscribe() { | |
for (let key in this.subscriptions) { | |
if (this.subscriptions.hasOwnProperty(key)) { | |
this.subscriptions[key].unsubscribe() | |
} | |
} | |
this.subscriptions = {} | |
} | |
render() { | |
return <ComposedComponent {...this.props} data={this.state} /> | |
} | |
} | |
Enhancer.propTypes = ComposedComponent.propTypes | |
Enhancer.contextTypes = ComposedComponent.contextTypes | |
return Enhancer | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment