我有点想到如何实现一个reducer,其实体可以有相同类型的子节点。
我们以reddit评论为例:每条评论都可以有儿童评论,可以自己评论等。
出于简化原因,评论是{id, pageId, value, children}
类型的记录,pageId
是红色页面。
如何对减速机进行建模?我在想减速器是地图 - >您可以使用pageId
按页面过滤的评论ID。
问题在于,例如当我们想要为嵌套的注释添加注释时:我们需要在地图的根上创建记录,然后在父子属性中添加其id。要显示我们需要获取所有这些注释的所有注释,请过滤掉我们在顶部的那些注释(例如,将它们作为orderedList保存在页面reducer中)然后迭代它们,从注释对象获取时我们遇到使用递归的孩子。
有没有比这更好的方法或有缺陷?
答案 0 :(得分:36)
对此的官方解决方案是使用normalizr来保持您的状态:
{
comments: {
1: {
id: 1,
children: [2, 3]
},
2: {
id: 2,
children: []
},
3: {
id: 3,
children: [42]
},
...
}
}
你是对的,你需要connect()
Comment
组件,这样每个人都可以递归地从Redux商店查询它感兴趣的children
:
class Comment extends Component {
static propTypes = {
comment: PropTypes.object.isRequired,
childComments: PropTypes.arrayOf(PropTypes.object.isRequired).isRequired
},
render() {
return (
<div>
{this.props.comment.text}
{this.props.childComments.map(child => <Comment key={child.id} comment={child} />)}
</div>
);
}
}
function mapStateToProps(state, ownProps) {
return {
childComments: ownProps.comment.children.map(id => state.comments[id])
};
}
Comment = connect(mapStateToProps)(Comment);
export default Comment;
我们认为这是一个很好的妥协。您将comment
作为道具传递,但组件会从商店中检索childrenComments
。
答案 1 :(得分:1)
您的商店(缩减器)结构可能与您想要的视图模型不同(您将其作为道具传递给组件)。您可以将所有注释保留在数组中,并通过mapStateToProps中的链接将它们映射到树中,这些链接位于高级&#39; smart&#39;零件。您将在reducer中获得简单的状态管理,并为要使用的组件提供便捷的视图模型。