简体   繁体   English

如何在ImmutableJS中存储和更新深层嵌套的结构

[英]How to store and update deeply nested structures in ImmutableJS

I am building little blog with react+redux and I cant figure out how should I go about replying to comments under blog post. 我正在用react + redux建立一个小博客,但我想不出该如何回复博客文章下的评论。 I am getting comments structure for one blog post which looks something like this. 我正在为一篇看起来像这样的博客帖子获取评论结构。

"[
{"_id":"5676ed8b9104691f3b85b687",
"content":"Lorem",
"creator":"Admin",
"replies":[
  {
    "_id":"5676ede4b7a9044c3c1d9641",
    "content":"Ipsum",
    "creator":"Admin",
    "replies":[
      {
        "_id":"5676eec224ab8fe23c7ce4c6",
        "content":"Dolor",
        "creator":"Admin",
        "replies":[]
      },
      {
        "_id":"5676eeda1c0e3d093d1f90a0",
        "content":"Sit",
        "creator":"Admin",
        "replies":[]
      }
    ]
  },
  {
    "_id":"5676ee5b4b03bbac3c1f7544",
    "content":"Amet",
    "creator":"Admin",
    "replies":[]
  },
  {
    "_id":"5676ee91c43c05c63c319ace",
    "content":"Sup",
    "creator":"Admin",
    "replies":[]
  }
]},
{...}
]

How do I store it in ImmutableJS state so I can easily add replies to comments based on their _id ? 如何将其存储在ImmutableJS状态下,以便可以基于_id轻松添加评论的回复? Also the comments have to be iterable because Im rendering them into comment tree afterwards but I dont think that should be a problem as long as ImmutableJS data structures are used. 另外,注释必须是可迭代的,因为之后我会将它们渲染到注释树中,但是只要使用ImmutableJS数据结构,我认为这不会成为问题。 Basically I dont know how I should implement this function in my reducer. 基本上我不知道如何在我的减速器中实现此功能。

[REPLY_COMMENT]: (state, { payload }) => {
  const { _id, comment } = payload
  let newState = ???
  return newState
}

EDIT 编辑

Here is jsbin showing what I am trying to achieve. 这是jsbin,显示我要实现的目标。 I just want to be able to reply to comments that's all 我只希望能够回复所有评论

You gotta break this down a bit. 你得把这个分解一下。

So firstly let's add the comments to an Immutable.Map 因此,首先让我们将注释添加到Immutable.Map

state = state.update('coolPostId', post => Immutable.fromJS(comments));

const replyToPostComment = {
  _id: '1234',
  content: 'Hello',
  creator: 'RandomUser',
  replies: []
};

You now have an Immutable.List under coolPostId , so you then want to update that list by push ing a new comment: 现在,在coolPostId下有一个Immutable.List ,因此您想通过push新注释来update该列表:

state = state.update('coolPostId', comment => comment.push(Immutable.fromJS(replyToPostComment)));

That'll pass your first test: 这将通过您的第一个测试:

const expected = state.get('coolPostId').last();
expect(expected.toJS()).to.deep.equal(replyToPostComment);

The second part is just as easy but you need to map cover your comments and check if the _id matches your metadata. 第二部分同样简单,但是您需要映射注释,并检查_id与您的元数据匹配。

Here's your setup: 这是您的设置:

const replyComment = {
  _id: '5678',
  content: 'Wellcome',
  creator: 'RandomUser2',
  replies: []
};

const reply = {
  postId: 'coolPostId',
  commentId: '1234',
  comment: replyComment
};

The next line depends on a function that will do the _id check, 下一行取决于将执行_id检查的函数,

state = state.get(reply.postId)
  .map(comment => addReply(comment)(reply));

And the final bit of the puzzle is the addReply predicate: 最后一个难题是addReply谓词:

const addReply = c => cr => c.get('_id') === cr.commentId ? c
  .update('replies', replies => replies.push(Immutable.fromJS(cr.comment)) ) : c;

Here is a full jsbin for review 这是完整的jsbin可供审查

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM