Home > Software design >  How to flatten React state of comment section?
How to flatten React state of comment section?

Time:01-27

This is my data:

{
  "currentUser": {
    "image": { 
      "png": "/src/assets/images/avatars/image-juliusomo.png",
      "webp": "/src/assets/images/avatars/image-juliusomo.webp"
    },
    "username": "juliusomo"
  },
  "comments": [
    {
      "id": 1,
      "content": "Impressive! Though it seems the drag feature could be improved. But overall it looks incredible. You've nailed the design and the responsiveness at various breakpoints works really well.",
      "createdAt": "1 month ago",
      "score": 12,
      "user": {
        "image": { 
          "png": "/src/assets/images/avatars/image-amyrobson.png",
          "webp": "/src/assets/images/avatars/image-amyrobson.webp"
        },
        "username": "amyrobson"
      },
      "replies": []
    },
    {
      "id": 2,
      "content": "Woah, your project looks awesome! How long have you been coding for? I'm still new, but think I want to dive into React as well soon. Perhaps you can give me an insight on where I can learn React? Thanks!",
      "createdAt": "2 weeks ago",
      "score": 5,
      "user": {
        "image": { 
          "png": "/src/assets/images/avatars/image-maxblagun.png",
          "webp": "/src/assets/images/avatars/image-maxblagun.webp"
        },
        "username": "maxblagun"
      },
      "replies": [
        {
          "id": 3,
          "content": "If you're still new, I'd recommend focusing on the fundamentals of HTML, CSS, and JS before considering React. It's very tempting to jump ahead but lay a solid foundation first.",
          "createdAt": "1 week ago",
          "score": 4,
          "replyingTo": "maxblagun",
          "user": {
            "image": { 
              "png": "/src/assets/images/avatars/image-ramsesmiron.png",
              "webp": "/src/assets/images/avatars/image-ramsesmiron.webp"
            },
            "username": "ramsesmiron"
          }
        },
        {
          "id": 4,
          "content": "I couldn't agree more with this. Everything moves so fast and it always seems like everyone knows the newest library/framework. But the fundamentals are what stay constant.",
          "createdAt": "2 days ago",
          "score": 2,
          "replyingTo": "ramsesmiron",
          "user": {
            "image": { 
              "png": "/src/assets/images/avatars/image-juliusomo.png",
              "webp": "/src/assets/images/avatars/image-juliusomo.webp"
            },
            "username": "juliusomo"
          }
        }
      ]
    }
  ]
}

and this is how i'd want it to look like, each comment to store the replies id's

{
    "currentUser": {
      "image": { 
        "png": "/src/assets/images/avatars/image-juliusomo.png",
        "webp": "/src/assets/images/avatars/image-juliusomo.webp"
      },
      "username": "juliusomo"
    },
    "comments": [
      {
        "id": 1,
        "content": "Impressive! Though it seems the drag feature could be improved. But overall it looks incredible. You've nailed the design and the responsiveness at various breakpoints works really well.",
        "createdAt": "1 month ago",
        "score": 12,
        "user": {
          "image": { 
            "png": "/src/assets/images/avatars/image-amyrobson.png",
            "webp": "/src/assets/images/avatars/image-amyrobson.webp"
          },
          "username": "amyrobson"
        },
        "replies": []
      },
      {
        "id": 2,
        "content": "Woah, your project looks awesome! How long have you been coding for? I'm still new, but think I want to dive into React as well soon. Perhaps you can give me an insight on where I can learn React? Thanks!",
        "createdAt": "2 weeks ago",
        "score": 5,
        "user": {
          "image": { 
            "png": "/src/assets/images/avatars/image-maxblagun.png",
            "webp": "/src/assets/images/avatars/image-maxblagun.webp"
          },
          "username": "maxblagun"
        },
        "replies": [ 3, 4 ]
      },
      {
        "id": 3,
        "content": "If you're still new, I'd recommend focusing on the fundamentals of HTML, CSS, and JS before considering React. It's very tempting to jump ahead but lay a solid foundation first.",
        "createdAt": "1 week ago",
        "score": 4,
        "replyingTo": "maxblagun",
        "user": {
          "image": { 
            "png": "/src/assets/images/avatars/image-ramsesmiron.png",
            "webp": "/src/assets/images/avatars/image-ramsesmiron.webp"
          },
          "username": "ramsesmiron"
        }
      },
      {
        "id": 4,
        "content": "I couldn't agree more with this. Everything moves so fast and it always seems like everyone knows the newest library/framework. But the fundamentals are what stay constant.",
        "createdAt": "2 days ago",
        "score": 2,
        "replyingTo": "ramsesmiron",
        "user": {
          "image": { 
            "png": "/src/assets/images/avatars/image-juliusomo.png",
            "webp": "/src/assets/images/avatars/image-juliusomo.webp"
          },
          "username": "juliusomo"
        }
      }
    ]
  }

So far I've used the data as it was, and I had a hard time setting the state later, and after reading the react docs (https://beta.reactjs.org/learn/choosing-the-state-structure#avoid-deeply-nested-state) I understood why it was so hard to manage. But the docs don't have any methods on how to flatten it

CodePudding user response:

Let the variable data be the input.

const modifiedComments = data.comments.map((comment) => {
  const replies = comment.replies.map((reply) => reply.id);
  const modifiedComment = {
    ...comment,
    replies,
  };

  return modifiedComment;
});

const final = { ...data, comments: modifiedComments };

CodePudding user response:

While for huge lists this is really not advisable, you can still do something like this

const replies = [];
// commentData is your incoming data
const data = {...commentData,
    comments: commentData.comments.map(comment => {
        if(comment.replies.length) {
            comment.replies = comment.replies.map(reply => {
                replies.push(reply);
                return reply.id;
            })
        }
        return comment;
    })
};
data.comments = data.comments.concat(replies);

Remember that this is not very flexible in cases where replies might again have comments/replies ( nested objects )

JS Fiddle - https://jsfiddle.net/7d61jsm3/

  • Related