一个应用的state树,存放了包括整个应用的ui状态、未同步到服务器的数据、缓存数据等。这个state的树就是一个普通的js对象,每一个属性对应一个子树,子树的属性又对应子子树,一层层向下延伸,所以如何组织state就很重要了。
一个博客有很多文章,每篇文章有很多评论,文章和评论又都是由用户产生的。那么这样的数据结构可能看上去就是这样的:
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:"......"
},
]
}
];
这个数据结构就很复杂,有些冗余数据,就会存在一些问题:
所以,redux管理关系数据或嵌套数据的通用做法是将其视作数据库,将数据按范式化存储。
所以对于上述的需求,数据可分为3类:博客:blogs、评论:comments、用户:users。那按上规则改动后的state可能是这样的:
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结构有以下特点:
将Redux视作数据库,所以在处理表与表关系的时候可以再生成一个”关联表“:
{
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 删除。