我决定使用 normalizr 并且我想出了一个递归复制器函数。它接受实体、模式和 keygen 函数,并根据模式递归更新任何嵌套实体,方法是为它们提供新的 id。在基本情况下(当没有进一步的嵌套实体时),它将返回更新其键的基本事物。
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;
这目前不支持schema.Array
为数组中的多个实体类型设置 normalizr。我目前没有使用 schema.Array 并且这种情况支持起来非常重要,但我会在未来考虑它。