我有几个状态实例,我需要支持复制某些状态片段的操作。例如,我的产品是一个调查构建器,所以当我复制一个问题时,我也想复制它的答案,而不是有多个问题指向相同的答案实例。
国家正常化:
questionsById: {
q01: {
...
answers: ["a01"],
...
}
}
answersById: {
a01: {...}
}
在调度QUESTION_DUPLICATE的动作时,我还要复制任何答案。目前我的QUESTION_DUPLICATE动作创建者还创建了一个新的答案键的映射列表,然后答案减少器使用它。
这种模式对我来说似乎很笨拙,特别是在考虑更深层重复的可能性时(例如,复制包含问题的Page,其中包含Answers ......)。深度复制规范化数据是否有更好的模式?
答案 0 :(得分:0)
答案可能围绕您通常如何处理数据的规范化和非规范化。例如,在我的博客文章Practical Redux, Part 8: Form Draft Data Management中,我重用了我现有的规范化逻辑(利用redux-orm库)来复制我所在州的“当前”和“草稿”切片之间要编辑的项目。因此,类似地,一种方法是将要复制的问题非规范化,然后重新规范化它(在动作创建者或缩减器中,如您所见)。
答案 1 :(得分:0)
我决定使用normalizr&我想出了一个递归复制器功能。它接受实体,模式和keygen函数,&通过为它们提供新的ID,以递归方式更新任何基于schemata的嵌套实体。在基本情况下(当没有其他嵌套实体时),它将返回基本事物并更新其键。
const duplicator = (entity, schema, keygen) => {
const newEntity = {
...entity,
[schema._idAttribute]: keygen(entity, schema)
};
if (Object.keys(schema.schema).length === 0) {
return newEntity;
}
return Object.keys(schema.schema).reduce(
(acc, nestedKey) => {
if (!entity.hasOwnProperty(nestedKey)) {
return acc;
}
if (!Array.isArray(schema.schema[nestedKey])) {
return {
...acc,
[nestedKey]: duplicator(
entity[nestedKey],
schema.schema[nestedKey],
keygen
)
};
}
return {
...acc,
[nestedKey]: acc[nestedKey].map((nestedEntity, index) =>
duplicator(nestedEntity, schema.schema[nestedKey][0], keygen)
)
};
},
{ ...newEntity }
);
};
export default duplicator;
目前不支持对数组中多个实体类型的normalizr进行schema.Array
设置。我目前没有使用schema.Array,这个案例对于支持来说非常重要,但我将在未来考虑它。