zlux
v0.8.8
Published
simple alternative for redux with OOP pattern
Downloads
55
Readme
write store with OOP pattern
#some points
##single store
has all about data
:
- state
- how to change state(dispatch actions)
so your code:
//class SimpleStore extends BaseStore...
//const store = new SingleStore();
store.dispatch({type:'SomeActionType'})
store.getState()
so one store for one state ,one dispatch,one reduce: your application will have many stores.For some complicated apps,you might write some messy code if you are not careful.but what the advantage?
dump components are not so much useful, components with its data are. For instance, UserList
component with UserList Data
is a useful module.
I can use UserList module
directly if other applications which needs user list
to some extend, component + data = module
So that one store for one state concerns about reuse
module,not so much about flexibility
.
##Most components just needs one store.
what about component needing more state?
first try
spilt
your componentManager for mixed state:
state:{ productList:[], userList:[] } //..dispatch for state,some actions change productList ,some change userList,some both;
use
MergedStore
const userListStore = new UserListStore() const productListStore = new ProductListStore() const mergedStore = new MergedStore({ productList:productListStore, userList:userListStore }) mergedStore.dispatch(productActionTypeOrUserActionType) mergedStore.getState() // => {productList:... , userList:...}
##Basic Use
Just extends BaseStore
,and implement reduce(action)
(action must be an object with type property) method
import Immutable from 'immutable';
import {BaseStore} from 'zlux'
const ActionTypes={
ADD:'ADD',
DELETE_BY_ID:'DELETE_BY_ID',
UPDATE:'UPDATE'
}
export default class SimpleStore extends BaseStore{
__className ='PostListStore'
state = new Immutable.List()
reduce(action){
if(action.type === ActionTypes.ADD){
return state.push(action.payLoad)
}
if(action.type === ActionTypes.DELETE_BY_ID){
let id = action.payLoad.id;
return state.filter(item=>{return item.id !==id})
}
if(action.type == ActionTypes.UPDATE){
var id = action.payLoad.id;
var index = state.findIndex(item=>{return item.id == id});
//if index == -1, 这里不考虑update时,没有相应item的情况
return state.set(index,action.payLoad)
}
return state; //default return origin state
}
//action methods for Convenience
//these methods should be called
add(payLoad){
this.dispatch({
type:ActionTypes.ADD,
payLoad
})
}
deleteById(payLoad){
this.dispatch({
type:ActionTypes.DELETE_BY_ID,
payLoad
})
}
update(payLoad){
this.dispatch({
type:ActionTypes.UPDATE,
payLoad
})
}
}
//use below
var ss = new SimpleStore()
ss.add({id:1,content:'hello'})
ss.update({id:1,content:'world'})
ss.deleteById({id:1})
##listeners
var ss = new SimpleStore()
ss.subscribe((action,store)=>{
const newState = store.getState();
//if newState != oldState, react component render;
})
##middleware
ss.use(
function(next,action,store){
console.log('before')
next()
console.log('after')
},
function(next){
if(isLogin){
next()
}
else{
goToLogin();
}
}
)
##mergedStore
use for object which value is store to the constructor,then use as singleStore.
warning:
you should only merge singleStore not mergedStore, it might make the app out of control.