Skip to content

Commit

Permalink
Add a mixins collection pack
Browse files Browse the repository at this point in the history
  • Loading branch information
goatslacker committed Feb 22, 2015
2 parents 7d4b6de + fb1823c commit c6acbf5
Show file tree
Hide file tree
Showing 5 changed files with 434 additions and 14 deletions.
80 changes: 80 additions & 0 deletions mixins/FluxyMixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// This mixin lets you setup your listeners. It is similar to Fluxible's mixin.
//
// Usage:
//
// mixins: [FluxyMixin],
//
// statics: {
// storeListeners: {
// doFoo: FooStore,
// doBar: BarStore
// }
// },
//
// doFoo: function (storeState) {
// this.setState({ foo: FooStore.getState() })
// },
//
// doBar: function (storeState) { },
//
// render: function () {
// // state will be in the keys you provided
// this.state.foo
// }
//
// ----
//
// You can also pass in an Array of stores to storeListeners:
//
// statics: {
// storeListeners: [FooStore, BarStore]
// }
//
// Changes will then be passed to a function `onChange` which you will have
// to define:
//
// onChange() {
// this.setState({
// foo: FooStore.getState(),
// bar: BarStore.getState()
// })
// }
//
var Subscribe = require('./Subscribe')

var FluxyMixin = {
componentDidMount: function () {
Subscribe.create(this)

var stores = this.constructor.storeListeners

if (Array.isArray(stores)) {
var handler = this.onChange
if (!handler) {
throw new ReferenceError(
handler + ' should exist in your React component but is not defined'
)
}

stores.forEach(function (store) {
Subscribe.add(this, store, handler)
}, this)
} else {
Object.keys(stores).forEach(function (handler) {
if (!this[handler]) {
throw new ReferenceError(
handler + ' does not exist in your React component'
)
}

Subscribe.add(this, stores[handler], this[handler])
}, this)
}
},

componentWillUnmount: function () {
Subscribe.destroy(this)
}
}

module.exports = FluxyMixin
19 changes: 8 additions & 11 deletions mixins/ListenerMixin.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
var MIXIN_REGISTRY = '_alt store listener registry_'
var Subscribe = require('./Subscribe')

var ListenerMixin = {
componentDidMount: function () {
Subscribe.create(this)
},

componentWillUnmount: function () {
this[MIXIN_REGISTRY].forEach(function (x) {
x.store.unlisten(x.handler)
})
this[MIXIN_REGISTRY] = []
Subscribe.destroy(this)
},

listenTo: function (store, handler) {
if (Array.isArray(store)) {
store.forEach(function (s) {
this[MIXIN_REGISTRY].push({ store: s, handler: handler })
s.listen(handler)
Subscribe.add(this, s, handler)
}, this)
} else {
this[MIXIN_REGISTRY].push({ store: store, handler: handler })
store.listen(handler)
Subscribe.add(this, store, handler)
}
}
}

ListenerMixin[MIXIN_REGISTRY] = []

module.exports = ListenerMixin
79 changes: 79 additions & 0 deletions mixins/ReactStateMagicMixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// This mixin automatically sets the state for you based on the key you provide
//
// Usage:
//
// mixins: [ReactStateMagicMixin],
//
// statics: {
// registerStores: {
// foo: FooStore,
// bar: BarStore
// }
// },
//
// render: function () {
// // state will be in the keys you provided
// this.state.foo
// this.state.bar
// }
//
// Alternatively:
//
// statics: {
// registerStore: FooStore
// },
//
// render: function () {
// // all of FooStore's state will be dumped into this.state
// this.state
// }
var Subscribe = require('./Subscribe')

var ReactStateMagicMixin = {
getInitialState: function () {
return this.getStateFromStores()
},

componentDidMount: function () {
Subscribe.create(this)

var stores = this.constructor.registerStores

if (this.constructor.registerStore && this.constructor.registerStores) {
throw new ReferenceError(
'You are attempting to use `registerStore` and `registerStores` ' +
'pick one'
)
}

if (this.constructor.registerStore) {
Subscribe.add(this, this.constructor.registerStore, this.altSetState)
} else {
Object.keys(stores).forEach(function (formatter) {
Subscribe.add(this, stores[formatter], this.altSetState)
}, this)
}
},

componentWillUnmount: function () {
Subscribe.destroy(this)
},

getStateFromStores: function () {
if (this.constructor.registerStore) {
return this.constructor.registerStore.getState()
}

var stores = this.constructor.registerStores

return Object.keys(stores).reduce(function (obj, key) {
return obj[key] = stores[key].getState(), obj
}, {})
},

altSetState: function () {
this.setState(this.getStateFromStores())
}
}

module.exports = ReactStateMagicMixin
22 changes: 22 additions & 0 deletions mixins/Subscribe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var MIXIN_REGISTRY = '_alt store listener registry_'

var Subscribe = {
create: function (context) {
context[MIXIN_REGISTRY] = []
},

add: function (context, store, fn) {
var handler = fn.bind(context)
context[MIXIN_REGISTRY].push({ store: store, handler: handler })
store.listen(handler)
},

destroy: function (context) {
context[MIXIN_REGISTRY].forEach(function (x) {
x.store.unlisten(x.handler)
})
context[MIXIN_REGISTRY] = []
}
}

module.exports = Subscribe
Loading

0 comments on commit c6acbf5

Please sign in to comment.