Update item in tree structure by reference and return updated tree structure

后端 未结 2 760
感动是毒
感动是毒 2021-01-23 17:30

I am currently learning functional programming using HyperappJS (V2) and RamdaJS. My first project is a simple blog app where users can comment on posts or other comments. The c

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-23 18:35

    Ramda is intentionally designed not to modify user data. Passing something by reference won't help; Ramda will still refuse to alter it.

    One alternative is to see if you can pass the path to the node to which you want to add the comment. Ramda can use a path with lensPath and over to make a version that will return a new state object, something like this:

    const addComment = (state, {text, path}) => 
      over (
        lensPath (['posts', ...intersperse ('comments', path), 'comments']), 
        append ({text, comments: []}), 
        state
      )
    
    const state = {
      posts: [
        {topic: `Topic A`, comments: []},
        {topic: `Topic B`, comments: [{text: `Comment`, comments: [
          {text: 'foo', comments: []}
          // path [1, 0] will add here
        ]}]},
        {topic: `Topic C`, comments: []}
      ],
      otherstuff: {}
    }
    
    console .log (
      addComment (state, {path: [1, 0], text: 'bar'})
    )
    //=> {
    //   posts: [
    //     {topic: `Topic A`, comments: []},
    //     {topic: `Topic B`, comments: [{text: `Comment`, comments: [
    //       {text: 'foo', comments: []}, 
    //       {text: 'bar', comments: []}
    //     ]}]},
    //     {topic: `Topic C`, comments: []}
    //   ],
    //   otherstuff: {}
    // }
    
    

    Here the path we use is [1, 0], representing the second post (index 1) and the first comment (index 0) within it.

    We could write more a more sophisticated lens to traverse the object if the path is not enough.

    I don't know if this is an overall improvement, but it's definitely a more appropriate use of Ramda. (Disclaimer: I'm one of the authors of Ramda.)

提交回复
热议问题