【问题标题】:How do I retain inheritance information in a flattened Redux store?如何在扁平化的 Redux 存储中保留继承信息?
【发布时间】:2015-11-19 09:19:56
【问题描述】:

我在 React 应用程序中使用 Redux 进行状态管理。我还打算“扁平化”任何 API 响应,以鼓励重用和减少跨状态树的数据重复。我希望使用Normalizr 来实现这一点。

我的问题是关于管理对象之间关系的首选方式——尤其是继承类型的关系。

应用程序向 API(用 Java、Spring 编写的后端)发出请求。已定义的领域模型包括以下关系:

interface NamedThing {
    int getId();
    String getName();
}

interface Pet extends NamedThing {
    Person getOwner();
}

class Cat implements Pet {
    int getId() {
        ...
    };
    String getName() {
        ...
    };
    Person getOwner() {
        ...
    };
    int getNumberOfLivesRemaining() {
        …
    };
}

class Dog implements Pet {
    int getId() {
        ...
    };
    String getName() {
        ...
    };
    Person getOwner() {
        ...
    };
    int getAgeInDogYears() {
        …
    };
}

class Person implements NamedThing {
    int getId() {
        ...
    };
    String getName() {
        ...
    };
}

对 /pets 端点的 GET 请求的响应可能如下所示:

[{
    id: 1,
    type: ‘cat',
    name: ‘Fluffy',
    owner: {
        id: 1,
        name: ‘Mary'
    },
    numberOfLivesRemaining: 9
},
{
    id: 2,
    type: ‘dog',
    name: ‘Ralph',
    owner: {
        id: 1,
        name: ‘Mary'
    },
    ageInDogYears: 10
}]

定义正确的模式后,Normalizr 会将响应扁平化,如下所示:

{
    result: [
        {id: 1, schema: ‘cats’},
        {id: 2, schema: ‘dogs’}
    ],
    entities: {
        cats: {
            1: {
                id: 1,
                type: ‘cat’,
                name: ‘Fluffy’,
                owner: 1,
                numberOfLivesRemaining: 9
            }
        },
        dogs: {
            2: {
                id: 2,
                type: ‘dog',
                name: ‘Ralph',
                owner: 1,
                ageInDogYears: 10
            }
        },
        persons: {
            1: {
                id: 1,
                name: ‘Mary’
            }
        }
    }
}

方法一:

不同的实体(猫、狗和人)可以存储在应用程序状态下类似命名的集合中。但是,我会丢失猫和狗是宠物的细节,因为我调用了 pets 端点,所以我知道这一点。

方法二:

我可以将所有宠物实体存储在一个宠物集合中,并将所有猫的 ID 和所有狗的 ID 存储在单独的集合中。然后,我可以通过使用React-Redux mapStateToProps 函数进行相应的过滤,将所有的猫、所有的狗或所有的宠物传递到一个组件中。

但是,如果我向 /namedThings 端点发出 GET 请求,我会返回猫、狗和人并将它们存储在 namedThings 集合中,其中包含猫、狗和人的 id 集合。但是,我不知道猫和狗也是宠物,因为这些信息不包含在 API 响应中。

为了解决这个问题,我可以:

  1. 更改 API 以使超类型信息包含在响应中
  2. 将猫和狗的集合映射到包含所有宠物的合并组件“prop”
  3. 让 reducer 知道猫是宠物,因此在将猫添加到 store 时将 id 添加到 pet id 集合中。

在使用 Redux 和 Normalizr 时,表示这种类型的实体层次结构的最佳方法是什么?其他团队如何解决这个问题?

【问题讨论】:

    标签: inheritance reactjs redux


    【解决方案1】:

    这两种方法听起来都不错:

    1. 将猫和狗的集合映射到包含所有宠物的合并组件“prop”

    2. 让 reducer 知道猫是宠物,因此在将猫添加到商店时将 id 添加到宠物 id 集合中。

    您应该同时尝试这两种方法,看看哪种方法更适合您的应用程序。

    【讨论】:

    • 感谢 Dan 和 Redux 等人的回复!明确地说,建议是这样的; 2. 将每个实体类型存储在单独的集合中,并且 3. 将所有 NamedThing 子类实体存储在单个集合中。在 Redux 中存储这样的实体是否有首选方法?您能否建议这两种方法的优缺点,或者提供一些标准来评估哪种方法最适合我的应用程序?即对测试和性能有什么影响?
    • 我没有看到任何重要的区别。我无法评估什么是最好的,因为我没有看到 UI、数据模型、需求等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 1970-01-01
    相关资源
    最近更新 更多