Skip to content

Instantly share code, notes, and snippets.

@rpominov
Last active January 31, 2016 22:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rpominov/57cfeac3397a4d04e71f to your computer and use it in GitHub Desktop.
Save rpominov/57cfeac3397a4d04e71f to your computer and use it in GitHub Desktop.
function loadSomeStuff(id) {
// We return basic-stream https://github.com/rpominov/basic-streams
return _sink => {
let sink = _sink
const onSuccess = data => sink({type: 'success', data})
const onError = error => sink({type: 'error', error})
stuffLoadingService.load(id).done(onSuccess, onError)
return () => {
// We can't unsubscribe from a Promise, so we simply make sink() a noop
sink = () => {}
}
}
}
const Subscribe = React.createClass({
componentDidMount() {
// We use `target` that was available at mount time, and the current `handler`
// (we can create versions of <Subscribe> with other strategies)
this._unsub = this.props.target(x => {
this.props.handler(x)
})
},
componentWillUnmount() {
this._unsub()
},
render() {
return null
}
})
// Imperetive (how we do it now, just for comparison)
{
componentDidMount() {
this._unsub = loadSomeStuff(this.props.id)(this.handleStuffLoaded)
},
componentWillUnmount() {
this._unsub()
},
handleStuffLoaded(stuff) {
this.setState({stuff})
},
render() {
const {stuff} = this.state
return <div>
{stuff ? <Stuff data={stuff} /> : 'loading...'}
</div>
}
}
// Declarative with help of <Subscribe/>
{
handleStuffLoaded(stuff) {
this.setState({stuff})
},
render() {
const {stuff} = this.state
return <div>
<Subscribe
// It's ok to call loadSomeStuff multiple times, it doesn't do anything by itself
target={loadSomeStuff(this.props.id)}
handler={this.handleStuffLoaded}
// Reloading when id changes for free (React remounts component when key changes)
key={this.props.id}
/>
{stuff ? <Stuff data={stuff} /> : 'loading...'}
</div>
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment