Redux 用于处理不同步的规范化状态的Reducer代码
假设我有一个规范化的状态,它看起来像这样,比如说一个待办事项列表:Redux 用于处理不同步的规范化状态的Reducer代码,redux,Redux,假设我有一个规范化的状态,它看起来像这样,比如说一个待办事项列表: { ids: [1,2,3,4], dataEntities: { 1: { //the todo item name, content, due date, etc}, 2: { //same } //etc.. }, metadataEntities: { 1: { //info about when the todo was last edited, saved to
{
ids: [1,2,3,4],
dataEntities: {
1: { //the todo item name, content, due date, etc},
2: { //same }
//etc..
},
metadataEntities: {
1: { //info about when the todo was last edited, saved to server, etc }
// etc..
}
}
当然,我已经编写了我的简化程序,因此每当我从ids
添加或删除某些内容时,我也会更新dataEntities
和metadataEntities
中的相应条目。因此,我的状态应该始终保持一致,即如果ids
中存在某个内容,那么它将在每个实体中都有条目。因此,依赖于这种一致性的减速器应该可以正常工作
例如,像这样的reducer操作应该可以(假设我使用的是RTK或Immer,所以编写一个明显的状态变化reducer是可以的):
换句话说,if
块中的语句应该是正确的。如果id存在于ids
中,则它应该在state.dataEntities和state.metaDataEntities中具有相应的实体。事实上,如果设置和维护这些实体的初始值设定项和还原项都被正确编写,那么情况将永远如此
但是。。。如果不是呢?一段杂乱的代码、一个奇怪的边缘案例等等——由于某种原因,事情变得“不同步”,即ids
中的一个id在其中一个实体数组中没有对应的实体。redux中减速器处理该问题的“正确”方法是什么
换句话说,我应该如何在此处填写缺失的代码:
const reducer = (state, action) => {
switch(action.type) {
//...
"editTodo":
const id = action.payload.id
const newTodoContent = action.payload.content
if(state.ids.includes(id)) {
if(state.dataEntities[id] === undefined || state.metadataEntities[id] === undefined
{
//WHAT GOES HERE?
}
state.dataEntities[id].content = newTodoContent
state.metaDataEntities[id].lastEdit = new Date().toString()
} else return
}
}
我考虑过几个选择:
state.stateError=“Inconsistent entity state”
(或者更具体的东西,理想情况下)
非常感谢。作为第一个观察,请注意这将为您完成大部分规范化更新工作。@markerikson,绝对是。事实上,我一直很难理解RTK如何处理这种情况,也就是说,在没有相应实体的情况下,可以要求reducer更新id。在我看来,从源代码(我可能读错了)来看,如果要求它更新一个没有相应实体的id,它只是不更新,而不是指示错误。也许这绝对是正确的方法,但这也是导致这个问题的部分原因。(同样,如果不感谢您在RTK上所做的所有工作,就不能不发表这一评论!)是的,还原程序应该确定响应任何给定操作的状态更新,并且“此操作没有更新”是完全有效的结果,即使它是还原程序确实关心的操作。这也适用于将动作建模为“事件”的建议方法。但是,这仍然取决于您决定这是否是您希望减缩器具有的语义。(哦,还有:谢谢,不客气!)
const reducer = (state, action) => {
switch(action.type) {
//...
"editTodo":
const id = action.payload.id
const newTodoContent = action.payload.content
if(state.ids.includes(id)) {
if(state.dataEntities[id] === undefined || state.metadataEntities[id] === undefined
{
//WHAT GOES HERE?
}
state.dataEntities[id].content = newTodoContent
state.metaDataEntities[id].lastEdit = new Date().toString()
} else return
}
}