我的问题是关于如何组织我的减速器。
让我们说我的状态是这样的:
resources: [
{
id: 1,
name: "John",
/* ... 100 more properties ... */
},
{
id: 1,
name: "Daniel",
/* ... 100 more properties ... */
},
]
events: {
planned: [
{
resourceId: 1,
name: "Concert with Adele",
/* ... 100 more properties ... */
}
]
}
首先,我们假设我们有一台减速机。业务逻辑是这样的:
有很多逻辑可以处理"资源"状态树的分支,同时有很多逻辑来处理事件"状态树的一部分。
点2,3和4引入了资源"之间的依赖关系。和"事件",我试图以最好的方式解决。
天真的解决方案
天真的解决方案是让一个减速器来处理所有动作。这样,当删除资源时,我们可以简单地删除资源,检查是否还有其他资源,然后相应地更新事件。但是,保持“资源”的逻辑。和'事件'在一起,只是因为这感觉不好。
维护自己的列表
另一种替代方法是将资源和事件的处理拆分为两个不同的reducer。在状态树的Events部分,我们可以保留一个可用的resourceId列表,以便我们知道如何更新我们的事件。我们仍然可以监听与资源缩减器相同的事件,但只保存相关数据。像
这样的东西resources: [
{
id: 1,
name: "John",
/* ... 100 more properties ... */
},
{
id: 2,
name: "Daniel",
/* ... 100 more properties ... */
},
]
events: {
resourceIds: [1,2], /* ADDED: Keeping track of available resources */
planned: [
{
resourceId: 1,
name: "Concert with Adele",
/* ... 100 more properties ... */
}
]
}
代理操作
第三个选项是为REMOVE_RESOURCE操作创建一个侦听器(例如redux-saga),然后触发另一个包含当前默认资源ID的操作UPDATE_DEFAULT_RESOURCE_ID。
对这里正确的做法有什么想法?
答案 0 :(得分:0)
我个人喜欢在ducks中拆分我的代码,并使用您在选项2中所述的规范化状态。每当我需要执行涉及两个或更多缩减器的复杂逻辑时,我使用redux-saga正如你在第三个选项中提到的那样。
这样做我保持" inter redurs"逻辑分离,更容易通过传奇测试。此外,您最终无法使用duck circle。
一般来说,当你看到圈子依赖时,它通常是设计不佳的强烈信号。
答案 1 :(得分:0)
链缩减器,以便更新事件的操作使用资源缩减器,它在保持依赖关系的同时分离两者的关注点。
event_reducer(state, action) {
switch(action.type) {
case 'REMOVE_RESOURCE_FROM_EVENT':
return {...state, resource_id: resource_reducer(null, action)}
}
}
resource_reducer(state, action) {
switch (action.type) {
case 'REMOVE_RESOURCE_FROM_EVENT':
let id = null;
if (resources.length > 0) {
id = resources[0].id;
resources = resources.slice(1);
}
return id;
}
}