如何在规范化的Redux存储中组织部分实体?

时间:2019-07-11 10:46:42

标签: javascript reactjs redux

出于项目的需要,我必须在两种方法中进行选择以在reducer中组织实体。

这种情况是API仅返回同一对象(在此示例中为汽车)的不同视图所需的数据。

因此,第一种方法是使用存储非标准化数据的标准化状态,但使用选择器来避免对象具有视图不需要的数据

const store = {
  entities: {
    car: {
      1: {
        id: 1,
        name: "SuperCar",
        date: "1992",
        constuctor: "Super Constructor",
      },
      2: {
        id: 2,
        name: "BasicCar",
        date: "1987",
        picture: "...",
        constuctor: "Amazing Constructor",
        possessors: [3,45,34]
      }
    },
    possessors: {
      /// ...
    }
  },
  requestResult: {
    car_for_list: [2],
    car_for_home: [1, 2],
  }
}
const getCarsForHome = state => state.requestResult.car_for_home.map(id => state.entities.car[id])

陷阱是:

  • 我不知道实体数据的一致性

我看到的第二种方法是考虑拥有一个主实体(例如父类)并使用选择器来获取视图的正确数据。 主实体拥有所有视图的所有共享属性,而特定实体拥有其他视图。

const store = {
  entities: {
    car: {
      1: {
        id: 1,
        name: "SuperCar",
        date: "1992",
        car_for_home: 1, // key to get the details for home view,
      },
      2: {
        id: 2,
        name: "BasicCar",
        date: "1987",
        car_for_home: 2, // key to get the details for home view,
        car_for_list: 2 // key to get the details for list view
      }
    },
    car_for_home: {
      1: {
        id: 1,
        constuctor: "Super Constructor",
      },
      2: {
        id: 2,
        constuctor: "Amazing Constructor",
      }
    },
    car_for_list: {
      2: {
        id: 2,
        picture: "...",
        possessors: [3,45,34]
      }
    },
    possessors: {
      /// ...
    }
  }
}
//Selector
const getCarsForHome = state => Object.values(state.entities.car_for_home).map( car => ({ ...state.entities.car[car.id], ...car }))

陷阱是:

  • 在更新或删除的情况下很难维护商店
  • 如果视图需要显示新属性,我可能不得不修改商店(例如:car_for_list现在需要构造函数,因此我必须将其存储在主car中)

那么,处理此问题的最佳方法是什么?

所以,您知道,该项目很大,可以生产并且可以扩展。

2 个答案:

答案 0 :(得分:1)

我将使状态尽可能简单,并像第一个示例中那样保持状态。 Typescript可以帮助保持数据的一致性,这将是您可以用来帮助第一个示例的界面:

Interface Car {
id: string;
name: string;
constructor: string;
pictures?: string[];
processor?: number[];
}

保留可能没有可选属性的属性,然后在必要时进行取消包装,以便在应用程序中的所有位置处理所有情况(未定义或设置)。这里的挑战是在选择器中保留类型权限,但是typescript具有很好的类型推断,如果您使用reselect,则此库的类型很好!

答案 1 :(得分:0)

我认为,状态不应该包含Vue的逻辑(就像第二种方法一样)。拾取数据时就像BDD(例如API)。因此,第一种方法具有选择器,可以根据自己的意愿拾取数据,这对我来说是最佳解决方案。