Redux 状态树结构:"same type of data with different format / amounts of detail"



我已经完成了Dan Abramov关于EggHead的介绍系列,并且正在开发一个真实世界的应用程序。这个域很复杂,所以我将使用一个经典的"博客"示例。

比方说,我们有一个"索引/列表"页面,在那里我们只需要显示博客文章的标题和简介。因此,我们有一个API端点来返回它,并将其存储在blogs.byId下的状态树中。

然后,当你点击一篇博客文章时,我们实际上需要更多的信息,例如完整的博客文章,以及标签和类别。让我们称之为"带有元数据的博客"。

扩展这个例子,可能还有另一个完全独立的页面,我想在其中显示一个包含最近3条评论的博客文章列表。让我们称之为"带评论的博客"。

我的问题是,我的状态树应该如何处理这些单独的例子,在这些例子中,我以不同的"格式"存储相同的"东西"?我最初的直觉是将它们视为完全独立的数据类型,因此我的状态树将具有例如:blogs.byIdblogsWithMetadata.byIdblogsWithComments.byId

然后,即使每一篇博客文章都缓存在blogs.byId部分,在我们需要查看博客文章的那一刻,该应用程序也会完全忽略blogs.byId的缓存,只查看blogsWithMetadata.byId——所以我们实际上是在构建3个独立的博客数据缓存,每个缓存都有不同的信息量,并将其视为像"博客"一样彼此无关,而像"小部件"一样完全无关的表

这是正确的吗?或者有更好的方法吗?

该应用程序目前将它们都放在同一个节点下,没有基于"格式"的区别,这造成了一个痛苦的世界。

可能有很多方法可以选择。其中之一是使用normalizer来构建数据。

你的博客文章可能会有一个API返回的数据结构,如下所示:

{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}],
"tags": [{
"id": "1",
"value": "awesome"
}, {
"id": "2",
"value": "journal"
}],
"categories": [{
"id": "1",
"value": "personal"
}, {
"id": "2",
"value": "life"
}]
}

在正常化之后,将看起来像这样:

{
entities: {
"post": { 
"123": { 
id: "123",
author: "1",
title: "My awesome blog post",
comments: ["324"],
tags: ["1", "2"],
categories: ["1", "2"],
}
},
"users": {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" }
},
"comments": {
"324": { id: "324", "commenter": "2" }
}
"tags": {
"1": { id: "1", "value": "awesome" },
"2": { id: "2", "value": "journal" },
}
"categories": {
"1": { id: "1", "value": "personal" },
"2": { id: "2", "value": "life" },
}
}
}

随后,如果需要,您可以为每个页面设置一个状态:

{
entities: {...},
ui: {
blogs: {
posts: [1, 2],
hasComments: false,
// Displaying the blogs with or without comments
// could simply just be a boolean flag in state.
},
}
}

使用reselect,然后创建选择器,将您想要作为道具的帖子传递到页面Components。

相关内容

最新更新