编辑:我最终选择了 Mobx.js,详情请参阅@mweststrate 答案。
所有关于 redux 的学习资源都展示了如何将它与普通对象模型一起使用。但是当你使用一些 es6 Class 模型时,我无法弄清楚如何使用它。
例如,让我们采用这种状态形状:
{
players:{
000:{
life:56,
lvl:4,
//...
},
023:{
life:5,
lvl:49,
//...
},
033:{
life:679,
lvl:38,
//...
},
067:{
life:560,
lvl:22,
//...
},
//...
}
而这个类(未测试)
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;
}
}
想象一下,我在 WorldCollection 中有 100 个玩家的集合。什么是最好的方法?
采取1:将所有属性从实例复制到状态树
{
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]
},
//...
}
这可以通过注入dispatch
构造函数来完成
//...
constructor({WorldCollection, dispatch})
//...
在每个 setter 中调度一个动作。
// setter
setHealth(hp){
this.life += hp;
dispatch({type:"HEAL_PLAYER", data:{id:this.id})
}
并将所有逻辑放在 reducer 中(setter 逻辑是确定性和原子性的)。
...
case "HEAL_PLAYER":
return {
...state,
life: state.life + action.hp
};
...
临:
- 恕我直言,在我看来,只有一个地方是所有状态的地方。
缺点:
- 所有逻辑都从模型中分散到另一个地方。我不喜欢增加文件。但也许这不是一个真正的问题?
- Redux 说逻辑必须放在 action 中,而不是 reducer 中。
- 该状态需要两倍的内存。我看到immutables.js可以对此进行优化,但我不确定。
采取 2:在 redux 状态树中只存储 id
{
players:[
001,
002
//...
]
}
这可以通过使用dispatch
in eachsetter
并在每个 setter 之后调度一个动作来完成
// setter
setHealth(hp){
this.life += hp;
dispatch({type:"PLAYER_UPDATED", data:{id:this.id})
}
当新的树状态改变时。我调用mapStateToProps
并WorldCollection.getPlayer()
检索正确的实例并将其属性映射到视图。
优点:
- 尊重 Redux 方式,不将逻辑放入 reducer
- 不是“重复状态”(如果 Immutables.js 无法优化)
- 逻辑在模型中(对我来说更有意义)
缺点:
- Redux 状态不代表整个状态
我希望我没有把这个案子简化太多。我的意思是澄清 redux 是否/如何与某些类模型一起使用。
采取 3:使用 Mobx.js 代替/与 Redux
---这里非常预实验---
一周前我发现了 Mobx.js,它的简单性/性能吸引了我。
我认为我们可以观察每个班级成员(共同构成应用程序状态)
@observable life; //int
@observable lvl; //int
@observable buffs; //[objects]
@observable debuffs; //[objects]
@observable inventory; //[objects]
在其他地方有一个构建状态树的类,也许 Redux 在这里有意义?(注意我不知道如何做这部分。必须在 Mobx 中更深入地挖掘)
对于我的情况,这是纯粹的 redux/mobx 比较中的优点/缺点。
优点:
- 不那么冗长
- 没有要继承的模型(如在 redux-orm 中)
- 性能已经过评估(所以我几乎不知道我要去哪里)
- 不要在类模型中编写“自以为是”的 reducer(只是 mutators)
缺点:
- 不知道如何实现重做/撤消(或游戏开发中的抖动缓冲区)
- 眨眼间拥有整个状态似乎不像 redux 中的“树”(对我来说这是 redux 的杀手级功能)