如何在Redux减速器中处理树形实体? [英] How to handle tree-shaped entities in Redux reducers?

查看:56
本文介绍了如何在Redux减速器中处理树形实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于如何实现一个减速器,它的实体可以具有相同类型的子代,我有些困惑.

I'm a bit stuck thinking on how to implement a reducer where its entities can have children of the same type.

让我们以reddit评论为例:每个评论可以包含子评论,而子评论本身也可以具有评论等. 为了简化起见,注释是类型为{id, pageId, value, children}的记录,其中pageId是reddit页面.

Let's take reddit comments as an example: each comment can have child comments that can have comments themselves etc. For simplification reason, a comment is a record of type {id, pageId, value, children}, with pageId being the reddit page.

如何围绕它建模减速器?我当时想让reducer成为评论的map-> id,您可以在其中使用pageId按页面进行过滤.

How would one model the reducer around that? I was thinking of having the reducer be a map -> id of the comments where you can filter by page using the pageId.

问题是,例如,当我们要向嵌套的注释添加注释时:我们需要在地图的根目录上创建记录,然后在父级children属性中添加其ID.要显示所有注释,我们需要获取所有注释,过滤掉我们顶部的注释(例如,将其作为orderedList保留在页面精简器中),然后对其进行迭代,在需要时从注释对象获取我们遇到了使用递归的孩子.

The issue is that for example when we want to add a comment to a nested one: we need to create the record on the root of the map and then add its id in the parent children property. To display all the comments we'd need to get all of them, filter those that we have at the top (that would be kept in the page reducers as an orderedList for example) and then iterate on them, fetching from the comments objects when we encounter children using recursion.

有没有比这更好的方法?还是有缺陷?

Is there a better approach than that or is it flawed?

推荐答案

对此的官方解决方案是使用 normalizr 使您的状态保持这种状态:

The official solution to this is to use normalizr to keep your state like this:

{
  comments: {
    1: {
      id: 1,
      children: [2, 3]
    },
    2: {
      id: 2,
      children: []
    },
    3: {
      id: 3,
      children: [42]
    },
    ...
  }
}

您是正确的,您需要connect() Comment组件,以便每个组件都可以从Redux存储中递归查询感兴趣的children:

You're right that you'd need to connect() the Comment component so each can recursively query the children it's interested in from the Redux store:

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.

We think this is a good compromise. You pass comment as a prop, but component retrieves childrenComments from the store.

这篇关于如何在Redux减速器中处理树形实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆