Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active August 13, 2016 17:54
Show Gist options
  • Save ryanflorence/7ed29703f24a093ad2ab9afb3b43ad1e to your computer and use it in GitHub Desktop.
Save ryanflorence/7ed29703f24a093ad2ab9afb3b43ad1e to your computer and use it in GitHub Desktop.
import { createStore, combineReducers } from 'redux'
const createInjectableStore = (createStore) => {
return (reducers) => {
const store = createStore(combineReducers(reducers))
const replace = () => {
store.replaceReducer(combineReducers(reducers))
}
store.injectReducer = (key, reducer) => {
reducers[key] = reducer
replace()
}
store.removeReducer = (key) => {
delete reducers[key]
replace()
}
return store
}
}
////////////////////////////////////////////////////////////
const reducer1 = () => 'one'
const reducer2 = () => 'two'
const store = createInjectableStore(createStore)({
reducer1,
reducer2
})
console.log(store.getState())
////////////////////////////////////////////////////////////
const reducer3 = () => 'injected!'
store.injectReducer('reducer3', reducer3)
console.log(store.getState())
////////////////////////////////////////////////////////////
const instanceId = 0
class CoolWidget extends React.Component {
static contextTypes = {
store: PropTypes.shape({
injectReducer: PropTypes.func.isRequired,
removeReducer: PropTypes.func.isRequired
})
}
componentWillMount() {
const { store } = this.context
if (!store) {
// make your own store, or just use component state
// if the data doesn't need to be shared across
// instances.
//
// The rest of the code in this fake component
// assumes there is a store to use from context
} else {
this.reducerId = `widget:${++instanceId}`
store.injectReducer(this.reducerId, widgetReducer)
store.subscribe(() => this.setState({
reducerState: store.getState()[this.reducerId]
}))
}
}
componentWillUnmount() {
this.context.store.removeReducer(this.reducerId)
}
shouldComponentUpdate(nextProps, nextState) {
return nextState.reducerState !== this.state.reducerState
}
handleClick() {
// now you can dispatch, and it's plugged into the app
this.context.store.dispatch(action)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment