从规范化的 redux 存储中删除项目
Posted
技术标签:
【中文标题】从规范化的 redux 存储中删除项目【英文标题】:Removing items from normalized redux store 【发布时间】:2017-02-24 15:21:06 【问题描述】:请先看这个问题here。我正在使用这个每个人都在使用的示例对象。
entities:
plans:
1: title: 'A', exercises: [1, 2, 3],
2: title: 'B', exercises: [5, 6]
,
exercises:
1: title: 'exe1',
2: title: 'exe2',
3: title: 'exe3'
5: title: 'exe5'
6: title: 'exe6'
,
currentPlans: [1, 2]
当用户点击“删除练习”时,消息可能如下所示:
type: "REMOVE_EXERCISE", payload: 2
我是否需要遍历所有计划,然后是每个计划中的所有练习才能删除此项目?这将如何在减速器中完成?
【问题讨论】:
Lodash 有一个很好的函数,叫做omit,它返回一个没有传入键的对象。您可以执行以下操作:omit(state.entities.exercises, 2)
。这有帮助吗?
要从每个plan.exercises
中删除,您可以使用Array.filter
函数来保留除已删除的ID之外的所有ID,例如:plan.exercises.filter(id => id!==2)
How do you add/remove to a redux store generated with normalizr?的可能重复
计划和练习之间的关系不是多对多的关系吗?因此,当您发送“REMOVE_EXERCISE”消息时,您应该知道练习属于哪个计划。只需将计划 ID 与消息一起发送,您就不必遍历所有计划。
您可以使用spread operator 隔离丢弃的密钥,然后返回...其余的。另一种方法是使用 Redux Toolkit 使用的Immer。但是@Andrey 提到的 lodash 省略可能是最好的。
【参考方案1】:
选项 A
只需删除exercise
并修改处理plans
的代码,也可以与undefined
对象一起使用(这两种方法都很方便)。减速器示例:
[REMOVE_EXERCISE]: (state, action) =>
const newState =
...state
delete newState.entities.exercises[action.payload] // deletes property with key 2
return newState;
选项 B
删除练习并通过所有plans
也删除引用。示例:
[REMOVE_EXERCISE]: (state, action) =>
const newState =
...state,
;
Object.keys(newState.entities.plans).map(planKey =>
const currentPlan = newState.entities.plans[planKey];
// Filters exercises array in single plan
currentPlan.exercises = currentPlan.exercises.filter(exercise =>
return exercise !== action.payload;
);
newState.entities.plans[planKey] = currentPlan;
);
delete newState.entities.exercises[action.payload];
return newState;
,
选择正确的选项取决于plans
的大小 - 当它增长到显着大小时,它可能会减慢处理速度。在这种情况下,您可以在这部分代码上设置速度测试,实现选项 B 并查看它是否/何时会成为瓶颈。
无论哪种方式,我都会更新使用 plans
数据的代码来处理 exercises
中的 undefined
值。这可以在选择器中轻松完成。
【讨论】:
以上是关于从规范化的 redux 存储中删除项目的主要内容,如果未能解决你的问题,请参考以下文章
从 redux 存储的列表中删除项目并重定向回列表 - 延迟道具评估?