1

我有几个状态实例,我需要支持复制某些状态片段的操作。例如,我的产品是一个调查生成器,所以当我复制一个问题时,我也想复制它的答案,而不是让多个问题指向相同的答案实例。

状态被标准化:

questionsById: {
  q01: {
    ...
    answers: ["a01"],
    ...
  }
}
answersById: {
  a01: {...}
}

在调度 QUESTION_DUPLICATE 的操作时,我还想复制任何答案。目前,我的 QUESTION_DUPLICATE 操作创建者还创建了一个新答案键的映射列表,然后答案缩减器使用它。

这种模式对我来说似乎很笨拙,尤其是在考虑更深层次的重复的可能性时(例如,复制一个包含问题的页面,其中包含答案......)。是否有更好的模式来深度复制标准化数据?

4

2 回答 2

1

答案可能与您通常如何处理数据的规范化和非规范化有关。例如,在我的博文 Practical Redux, Part 8: Form Draft Data Management中,我重用了我现有的规范化逻辑(它利用了redux-orm库)在“当前”和“草稿”切片之间复制要编辑的项目在我的状态。因此,类似地,一种方法是对要复制的问题进行非规范化,然后对其进行重新规范化(在您认为合适的操作创建者或减速器中)。

于 2017-06-29T02:12:39.980 回答
0

我决定使用 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 并且这种情况支持起来非常重要,但我会在未来考虑它。

于 2017-06-30T23:46:26.773 回答