前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redux(三):组织state

Redux(三):组织state

原创
作者头像
Ashen
修改2020-06-01 14:30:03
3710
修改2020-06-01 14:30:03
举报
文章被收录于专栏:Ashenの前端技术Ashenの前端技术

一个应用的state树,存放了包括整个应用的ui状态、未同步到服务器的数据、缓存数据等。这个state的树就是一个普通的js对象,每一个属性对应一个子树,子树的属性又对应子子树,一层层向下延伸,所以如何组织state就很重要了。

一个博客有很多文章,每篇文章有很多评论,文章和评论又都是由用户产生的。那么这样的数据结构可能看上去就是这样的:

代码语言:javascript
复制
const state = [
  {
    id:"blog1",
    author:{username:"user1",name:"User 1"},
    body:"......",
    comments:[
      {
        id:"comment1",
        author:{username:"user2",name:"User 2"},
        comments:"......"
      },
      {
        id:"comment2",
        author:{username:"user3",name:"User 3"},
        comments:"......"
      },
    ]
  },
  {
    id:"blog2",
    author:{username:"user2",name:"User 2"},
    body:"......",
    comments:[
      {
        id:"comment3",
        author:{username:"user3",name:"User 3"},
        comments:"......"
      },
      {
        id:"comment4",
        author:{username:"user1",name:"User 1"},
        comments:"......"
      },
      {
        id:"comment5",
        author:{username:"user3",name:"User 3"},
        comments:"......"
      },
    ]
  }
];

这个数据结构就很复杂,有些冗余数据,就会存在一些问题:

  1. 更新时很难保证所有的数据都进行更新
  2. 嵌套越深,修改底层的数据需要进行非常复杂的遍历
  3. 不可变的数据在更新时需要被复制,尽管数据并没有发生变化,但底层数据的改变会强制无关的UI重新渲染

所以,redux管理关系数据或嵌套数据的通用做法是将其视作数据库,将数据按范式化存储。

范式化的state

  • 任何类型的数据在 state 中都有自己的 “表”。
  • 任何 “数据表” 应将各个项目存储在对象中,其中每个项目的 ID 作为 key,项目本身作为 value。
  • 任何对单个项目的引用都应该根据存储项目的 ID 来完成。
  • ID 数组应该用于排序。

所以对于上述的需求,数据可分为3类:博客:blogs、评论:comments、用户:users。那按上规则改动后的state可能是这样的:

代码语言:javascript
复制
const state = {
  blogs:{
    byId:{
      blog1:{
        id:"blog1",
        author:"user1",
        body:"......",
        comments:["comment1","comment2"]
      },
      blog2:{
        id:"blog2",
        author:"user2",
        body:"......",
        comments:["comment3","comment4","comment5"]
      }
    },
    allIds : ["blog1", "blog2"]
  },
  users:{
    byId:{
      user1:{
        username:"user1",
        name:"User 1"
      },
      user2:{
        username:"user2",
        name:"User 2"
      },
      user3:{
        username:"user3",
        name:"User 3"
      },
    },
    allIds : ["user1","user2","user3"]
  },
  comments:{
    byId:{
      comment1:{
        id:"comment1",
        author:"user2",
        comment:"......"
      },
      comment2:{
        id:"comment2",
        author:"user3",
        comment:"......"
      },
      comment3:{
        id:"comment3",
        author:"user3",
        comment:"......"
      },
      comment4:{
        id:"comment4",
        author:"user1",
        comment:"......"
      },
      comment5:{
        id:"comment5",
        author:"user3",
        comment:"......"
      },
    },
    allIds : ["comment1","comment2","comment3","comment4","comment5"]
  }
};

这样的state结构有以下特点:

  1. 每个数据只在一个地方定义,避免了冗余导致更新可能不彻底的问题
  2. 以对象代替数组,避免了深层遍历的问题
  3. 每个数据类型比较唯一。比如想更新某个评论,只需要”comments>byId>comment“这样的复制,避免了之前全部数据格式的复制导致的额外的渲染更新,提升整体的state渲染性能。

表间关系

将Redux视作数据库,所以在处理表与表关系的时候可以再生成一个”关联表“:

代码语言:javascript
复制
{
  entities: {
    authors : { byId : {}, allIds : [] },
    books : { byId : {}, allIds : [] },
    authorBook : {
      byId : {
        1 : {
          id : 1,
            authorId : 5,
            bookId : 22
        },
        2 : {
          id : 2,
            authorId : 5,
            bookId : 15,
        }
        3 : {
          id : 3,
            authorId : 42,
            bookId : 12
        }
      },
      allIds : [1, 2, 3]
    }
  }
}

如”查找某个作者的所有书“,结合Object.values()或Object.entries()方法,只需要遍历一次即可。

嵌套数据范式化

通常服务端返回的都是数组的嵌套格式,如果想转化成我们这样的格式可能需要编写一些转换函数,推荐使用normalizr来实现。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 范式化的state
  • 表间关系
  • 嵌套数据范式化
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档