EDIT: I finally choosed Mobx.js, refer to @mweststrate answer for details.
All learning ressources about redux show how to use it with plain object models. But I can't figure out how to use it when you use some es6 Class models.
For example, let's take this state shape:
{
players:{
000:{
life:56,
lvl:4,
//...
},
023:{
life:5,
lvl:49,
//...
},
033:{
life:679,
lvl:38,
//...
},
067:{
life:560,
lvl:22,
//...
},
//...
}
And this class (not tested)
class Player{
id; //int
life; //int
lvl; //int
buffs; //[objects]
debuffs; //[objects]
inventory; //[objects]
_worldCollection; //this class know about the world they belongs to.
constructor({WorldCollection}){
this._worldCollection = WorldCollection;
}
healPlayer(targetId, hp){
this._worldCollection.getPlayer(targetId).setHealth(hp);
}
// setter
setHealth(hp){
this.life += hp;
}
}
Imagine I have a collection of 100 players in WorldCollection. What is the best way?
{
players:{
001:{
life: 45,
lvl: 4,
buffs: [objects]
debuffs:[objects]
inventory:[objects]
},
034:{
life: 324,
lvl: 22,
buffs: [objects]
debuffs:[objects]
inventory:[objects]
},
065:{
life: 455,
lvl: 45,
buffs: [objects]
debuffs:[objects]
inventory:[objects]
},
//...
}
This could be done by injecting dispatch
in the constructor
//...
constructor({WorldCollection, dispatch})
//...
Dispatch an action in each setter.
// setter
setHealth(hp){
this.life += hp;
dispatch({type:"HEAL_PLAYER", data:{id:this.id})
}
And put all the logic in reducers (setter logic being deterministic and atomic).
...
case "HEAL_PLAYER":
return {
...state,
life: state.life + action.hp
};
...
Pro:
Cons:
{
players:[
001,
002
//...
]
}
This could be done by also using dispatch
in each setter
and dispatch an action after each setter
// setter
setHealth(hp){
this.life += hp;
dispatch({type:"PLAYER_UPDATED", data:{id:this.id})
}
When the new tree state is changed. I call mapStateToProps
and WorldCollection.getPlayer()
to retrieve the right instance and map its properties to the view.
Pros:
Cons:
I hope I have not simplified the case too much. My point is to clarify if/how redux could be use with some class models.
--- very pre-experimental here ---
I discovered Mobx.js a week ago and its simplicity/perf had me.
I think we could observe each class members (which together form the app state)
@observable life; //int
@observable lvl; //int
@observable buffs; //[objects]
@observable debuffs; //[objects]
@observable inventory; //[objects]
and somewhere else have a class which builds the state tree, maybe Redux could make sense here? (Note I have no clue how to do this part. Have to dig more deeply in Mobx)
This is pros/cons in a pure redux/mobx comparaison for my case.
Pros:
Cons:
You might want to look at redux-orm, which pretty much does this already. It provides a nice Model-like facade over the actual plain object data in your Redux state, and handles relational data very nicely.
I would like to add that if you were to go with Redux you would not store state in classes at all. In Redux, this logic would be described in reducers which would operate on plain objects rather than class instances. You would keep the data normalized so each entity is kept in an object map by its ID, and any reference to child entities would be an array of IDs rather than a real reference. You would then write selectors to reconstruct the parts of the data you care about for rendering.
You might find this discussion helpful, as well as these two examples:
(MobX author). For a short answer on the questions about MobX:
Redo / undo can be implemented in two ways:
Single state tree:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With