【发布时间】:2016-11-22 01:46:46
【问题描述】:
Redux 建议使用规范化的应用程序状态树,但我不确定这是否是这种情况下的最佳实践。假设以下情况:
- 每个
Circlehas_manyPosts。 - 每个
Posthas_manyComments。
在后端的数据库中,每个模型如下所示:
圈子:
{
_id: '1'
title: 'BoyBand'
}
帖子:
{
_id: '1',
circle_id: '1',
body: "Some Post"
}
评论:
{
_id: '1',
post_id: '1',
body: "Some Comment"
}
在前端的应用状态(所有reducer的最终结果)是这样的:
{
circles: {
byId: {
1: {
title: 'BoyBand'
}
},
allIds: [1]
},
posts: {
byId: {
1: {
circle_id: '1',
body: 'Some Post'
}
},
allIds: [1]
},
comments: {
byId: {
1: {
post_id: '1',
body: 'Some Comment'
},
allIds: [1]
}
}
现在,当我转到CircleView 时,我从后端获取Circle,该后端返回与之关联的所有posts 和comments。
export const fetchCircle = (title) => (dispatch, getState) => {
dispatch({
type: constants.REQUEST_CIRCLE,
data: { title: title }
})
request
.get(`${API_URL}/circles/${title}`)
.end((err, res) => {
if (err) {
return
}
// When you fetch circle from the API, the API returns:
// {
// circle: circleObj,
// posts: postsArr,
// comments: commentsArr
// }
// so it's easier for the reducers to consume the data
dispatch({
type: constants.RECEIVE_CIRCLE,
data: (normalize(res.body.circle, schema.circle))
})
dispatch({
type: 'RECEIVE_POSTS',
data: (normalize(res.body.posts, schema.arrayOfPosts))
})
dispatch({
type: 'RECEIVE_COMMENTS',
data: (normalize(res.body.comments, schema.arrayOfComments))
})
})
}
到目前为止,我认为我所做的一切都是相当标准的。但是,当我想渲染每个 Post 组件时,我意识到与将状态树保持在以下格式时相比,使用它们的 cmets 填充帖子变得效率低下 (O(N^2))。
{
circles: {
byId: {
1: {
title: 'BoyBand'
}
},
allIds: [1]
},
posts: {
byId: {
1: {
circle_id: '1',
body: 'Some Post'
comments: [arrOfComments]
}
},
allIds: [1]
}
}
这违背了我的理解,在 redux 状态树中,最好保持一切正常化。
问。在这样的情况下,我实际上是否应该保持非规范化?我如何确定要做什么?
【问题讨论】:
-
您是担心性能、重建树还是什么?
-
你能添加造成性能瓶颈的代码吗?组件和容器代码可能吗?
-
因为您的方法没有什么不好,您只需根据评论的 id 选择 cmets 正文,即使它是 O(n^2) 其中 n 是帖子的数量,它不应该是太多了。