Redux---State范式化

2018-11-02  本文已影响0人  捡了幸福的猪

许多API现在返回的JSON数据都嵌套层级很深,很难直接在应用中直接使用,尤其是在使用 Redux这类库时。
在 Redux Store 中管理关系数据或嵌套数据的推荐做法是将这一部分视为数据库,并且将数据按范式化存储

  1. 范式化的数据的特点:
  1. 🌰:

    以下面的原数据为例子: image.png
    数据特点是categorys为数组类型,包括所有菜单, 每个菜单category 包括此菜单下的所有菜dish, 每道菜包括此菜的所有价格price。数据嵌套级别过深,范式化处理。

处理后数据结构为:

reducer = {
   categoriesIds: [cateId],
   categories: {
      cateId: {
        ...cateObj,
         dishes:[dishId],
       },
   },
   dishes: {
     dishId: {
       ...dishesObj,
       prices: [priceId]
     }
   },
   prices: {
     priceId: priceObj
   },
 }
  1. 手动实现(同事大神把FP用的出神入化)
import * as R from 'ramda';
const pair = R.compose(
R.fromPairs,
R.map(item => ([
  item.id,
  item,
]))
);
const format = ({ key, list, handle = R.identity }) => R.compose(
pair,
R.map(item => ({
  ...R.omit([key], item),
  [key]: R.pluck('id', handle(item[key])),
}))
)(list);
const paradig =  (data) => {
const { categorys } = data;
const categories = format({ key: 'dishes', list: categorys });
const myDishes = R.flatten(R.pluck('dishes', categorys));
const dishes = format({
  key: 'prices',
  list: myDishes,
  handle: R.sort((a, b) => a.price - b.price),
});
const prices = pair(R.flatten(R.pluck('prices', myDishes)));
const categoryIds = R.pluck('id', categorys);
return { categoryIds, categories, dishes, prices };
};

4. Normalizr 通过定义schema,将JSON数据处理成带有ID的嵌套entities,这些entities 存储在dictionaries中。

Normalizr 处理不同的JSON数据类型,使用 不同的schema的方法,包括 Array、Entity、Object、Union以及values。 Entity 类似于标注中的实体概念,为一个处理对象。

使用 Normalizr 处理过程为:

    const price = new schema.Entity('prices');
    const dish = new schema.Entity('dishes',{
      prices: [price]
    });
    const category = new schema.Entity('category',{
      dishes: [dish]
    })
    const myCategorys = {
      categorys: [category]
    }
    const normalizedData = normalize(data.data, myCategorys);

Normalizr真是简直了。。

上一篇下一篇

猜你喜欢

热点阅读