Created
October 15, 2015 15:33
-
-
Save glortho/458bc65fee43fb9873e1 to your computer and use it in GitHub Desktop.
Decorator/higher-order React component for binding view-controllers to stores in Flux pattern
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
import React from 'react'; | |
import autobind from 'autobind-decorator'; | |
// Note: Assumes stores have a unique `key` prop and a `getState()` method | |
function listenTo( stores = [] ) { | |
const storesArray = [].concat( stores ); | |
return function listenToDecorator( WrappedComponent ) { | |
class StoreListener extends React.Component { | |
constructor( props ) { | |
super( props ); | |
this.state = storesArray.reduce( ( memo, { key, getState } ) => { | |
memo[ key ] = getState(); | |
return memo; | |
}, {} ); | |
} | |
componentDidMount() { | |
this._bindings = new Map(); | |
// loop through stores being listened to and add change listeners to each. | |
// store these bindings in an array so that they can be unbound on unmount. | |
storesArray.forEach( store => { | |
const listener = this._onChange.bind( this, store ); | |
store.addChangeListener( listener ); | |
this._bindings.set( store, listener ); | |
}); | |
} | |
componentWillUnmount() { | |
if ( this._bindings.size ) { | |
this._bindings.forEach( ( listener, store ) => store.removeChangeListener( listener ) ); | |
this._bindings.clear(); | |
} | |
} | |
@autobind | |
_onChange( store ) { | |
this.setState( { [ store.key ]: store.getState() } ); | |
} | |
render() { | |
return <WrappedComponent {...this.props} {...this.state} />; | |
} | |
} | |
return StoreListener; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment