Let's say I have an api endpoint
/categories
which returns an array of categories
[
{
id: '1'
name: 'category-1'
},
{
id: '2'
name: 'category-2'
}
...
]
和端点,用于检索
items/:categoryId
类别中的项目,该项目返回项目数组[
{ id: '1', name: 'item-1' },
{ id: '2', name: 'item-2' }
...
]
在UI上,我显示了一个类别列表,可以展开并延迟加载项目列表。
我希望能够扩展多个类别,并且需要能够添加,编辑和删除项目。
为此类场景组织状态的最佳方法是什么?
此刻,我的状态如下:
{
entities: {
categories: {
'1': {
id: '1'
name: 'category-1'
},
'2': {
id: '2'
name: 'category-2'
},
...
},
items: {
'1': {
id: '1'
name: 'item-1'
},
'2': {
id: '2'
name: 'item-2'
},
...
}
},
categories: {
ids: ['1', '2', ...],
isFetching: bool
error: null
},
itemsByCategory: {
'1': {
ids: ['1', '2',...]
isFetching: bool,
error: null
}
...
}
}
在
itemsByCategory
中,键是类别的ID,如果尚未加载给定类别的项目,则该键将不存在于itemsByCategory
上。此解决方案有效,但有一些缺点。为了删除项目,我必须传递两个键(项目ID和类别ID),而不只是项目ID(我也可以遍历所有类别以找到项目,但可能会变慢)。
I am also not happy with checking if items for given category were loaded. (first I have to check if the key with category id is defined on
itemsByCategory
), so my selectors become a little bit complicated.
在这种情况下,有没有更好的方法来调整状态?
最佳答案
如果category
是item
的属性,则每个项目都应具有categoryId
属性,以便仅存储对其的引用并避免在各处复制类别。如果API调用返回的项目不包括类别,则您可以在从API获得结果后立即分配类别,因为您知道类别是因为您首先使用它来检索项目。categories
和itemsByCategory
都通过存储元素的ID来复制entites
中已经具有的信息,而无需存储这些ID。
如果您唯一要延迟加载的是每个类别的项目,请在categories
中创建一个已加载类别的数组,以检查是否必须进行API调用。itemsByCategory
对我来说似乎完全没有用,除非您也懒惰地加载有关每个项目的更多信息。
只要您仅针对那些扩展的类别,我就不用担心遍历所有项目以检索与每个类别相对应的项目。毕竟React应该以这种方式使用,并且真的很擅长。如果您遇到性能问题,可能是因为您要更改父组件并强制重新呈现所有列表。
如果所有这些都失败了,那么您将要渲染的数据太多,您可能会重新考虑UI并添加某种分页类型。
另一个选择是,当类别折叠后,从entities
中清除项目,然后从已加载项目的列表中删除该类别,但这可能会对您的用户产生负面影响。
关于redux - 如何在Redux中为每个类别的延迟加载项构建状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38931619/