How to push Value in an array exist inside in an object of state in react

I’m new to React and working on a project of comments nesting as we see in facebook and youtube comments section. I have created states to manage nesting. This is a single comment state:

const [comment, setComment] = useState({author:"", desc:"",replies:[]});

I’m managing the list of comments in an array:

const [comments, setComments] = useState([]);

I have managed to add or remove the comment from comments state like this:

const addComment=()=>{
     if(comment.desc !== ""){
      setComments((prevComments)=>{
        return  [...prevComments, comment]
      });
      setComment({author:"", desc:"", replies:[]});
      setIsCommentVisible(true);
     }
   }


   const removeComment=(id)=>{
      setComments((prevComments)=>{
       return prevComments.filter((val, ind)=> ind !==id);
      });
   }

but I am having a problem in adding a reply in an array of objects into its replies property which is also an array.

So I want to know the approach to get a specific comment by its id and push a reply into its replies property.

//This is what I have tried
 const addReply=(id, reply)=>{
    setComments((prevComments)=>{
      return [...prevComments, /*So what's the approach here how to get
 access to the specific indexed replies property and push a reply into it.*/]
    });
   }

Answer

It sort of looks like you are using the current index to update state.

Shallow copy the state, and any nested state, that is being updated. Use the id to match to the currently mapped comment state, and when you are on the comment you want to update, shallow copy the comment and update the replies property by appending the reply and returning a new array reference.

const addReply = (id, reply) => {
  setComments(prevComments => prevComments.map(
    (comment, index) => index === id 
      ? {
        ...comment,
        replies: comment.replies.concat(reply)
      }
      : comment
    )
  );
}

Ideally your comment objects would have a GUID assigned to them, this way it’s easier to match them independently of any array sorted order or any other issues that pop up when mutating arrays in React.

Example:

import { v4 as uuidV4 } from 'uuid';

...

const addComment = () => {
  if (comment.desc !== "") {
    setComments((prevComments) => {
      return [...prevComments, { ...comment, id: uuidV4() }]
    });
    setComment({ author: "", desc: "", replies: [] });
    setIsCommentVisible(true);
  }
} 

const addReply = (id, reply) => {
  setComments(prevComments => prevComments.map(
    (comment) => comment.id === id 
      ? {
        ...comment,
        replies: comment.replies.concat(reply)
      }
      : comment
    )
  );
}