При обновлении стейта вложенные чилдрены схлопываются

У меня есть список комментариев, полученный с сервера(массив объектов содержащих свойство parent:id родительского комментария). При помощи написанной в CommentsList функции nestComments я получаю комментарии со свойством children, в котором лежит массив вложенных в данный коммент комментариев, передаю их в компонент Comment в качестве пропса childrenComments и далее в компоненте Comment я отображаю их при помощи рекурсии. У каждого комментария есть опция лайка. По заданию не предусмотрено никаких запросов к серверу по изменению количества лайков каждого отдельного комментария, изменяется только общее количество лайков в шапке через экшен к стору + изменяем количество лайков локально у каждого комментария при помощи useState. Проблема следующая: при клике на лайк у комментария с чилдренами(вложенными комментариями) все вложенные комментарии схлопываются. Предполагаю что это происходит из-за ререндера и нужно вложенные комментарии мемоизировать, React.memo эффекта не дал, что-то не то делаю... Помогите пожалуйста решить эту проблему! Заранее благодарю. Ссылка на гит с кодом: https://github.com/Kohlenbaron28/kefir

//CommentsList.tsx
    import {useState, useEffect, memo, useCallback, useMemo} from "react";
    import {useSelector, useDispatch} from "react-redux";
    import {formatDistanceToNow} from "date-fns";
    import {HeartFilled, HeartOutlined} from "@ant-design/icons";

    import {IState} from "../../types/IState";
    import {ICommentProps} from "../../types/ICommentProps";
    import * as actions from "../../store/actions";
    import styles from "./Comment.module.scss";

    const Comment = ({
        avatar,
        name,
        text,
        created,
        likes,
        childrenComments,
    }: ICommentProps) => {
        const dispatch = useDispatch();
        const [liked, setLiked] = useState(false);
        const authors = useSelector((state: IState) => state.authors);
        childrenComments = useMemo(() => childrenComments, [childrenComments]);
        const handleClick = async () => {
            await setLiked((prev: any) => !prev);
            if (!liked) {
                dispatch(actions.incrementLikes());
            } else dispatch(actions.decrementLikes());
        };
        const elems =
            childrenComments !== undefined && childrenComments.length > 0 ? (
                <ul>
                    {childrenComments.map((child, i, arr) => {
                        console.log(childrenComments, name);
                        arr.pop();
                        const pers = authors?.filter(
                            (el) => el.id === child.author,
                        )[0];
                        const MComment = memo(Comment);
                        return (
                            <MComment
                                avatar={pers?.avatar}
                                name={pers?.name}
                                created={child.created}
                                likes={child.likes}
                                text={child.text}
                                childrenComments={child.children}
                                key={child.id}
                                type="child"
                            />
                        );
                    })}
                </ul>
            ) : null;
        console.log(elems);
        return (
            <li className={styles["comment"]}>
                <section>
                    <div className={styles["comment__right"]}>
                        <div className={styles["comment__image"]}>
                            <img src={avatar} alt="avatar" />
                        </div>
                        <div className={styles["comment__text"]}>
                            <h2>{name}</h2>
                            <span className={styles["comment__time"]}>
                                {formatDistanceToNow(new Date(created))}
                            </span>
                            <p>{text}</p>
                        </div>
                    </div>

                    <figure onClick={handleClick}>
                        {liked ? <HeartFilled /> : <HeartOutlined />}
                        <figcaption>{liked ? ++likes : likes}</figcaption>
                    </figure>
                </section>
                {elems}
            </li>
        );
    };

    export default memo(Comment);
//Comment.tsx
    import { useEffect } from "react";
    import { connect, useSelector } from "react-redux";
    import { bindActionCreators } from "redux";

    import { IState } from "../../types/IState";
    import { ICommentsListProps } from "../../types/ICommentsListProps";
    import Comment from "../Comment/Comment";
    import * as actions from "../../store/actions";
    import styles from "./CommentsList.module.scss";

    const CommentsList = ({ firstRender, comments }: ICommentsListProps) => {
      useEffect(() => {
        firstRender();
      }, []);
      const authors = useSelector((state: IState) => state.authors);

      const nestComments = (commentList: any) => {
        const commentMap: { [key: string]: any } = {};
        commentList.forEach((comment: any) => (commentMap[comment.id] = comment));
        commentList.forEach((comment: any) => {
          if (comment.parent !== null) {
            const parent = commentMap[comment.parent];
            parent && (parent.children = parent.children || []).push(comment);
          }
        });
        return commentList.filter((comment: any) => {
          return comment.parent === null;
        });
      };

      return (
        <ul className={styles["commentsList"]}>
          {nestComments(comments).map((comment: any) => {
            const pers = authors.filter((el) => el.id === comment.author)[0];
            return (
              <Comment
                key={comment.id}
                avatar={pers?.avatar}
                name={pers?.name}
                created={comment.created}
                likes={comment.likes}
                text={comment.text}
                childrenComments={comment.children}
              />
            );
          })}
        </ul>
      );
    };

    const mapStateToProps = (state: IState) => {
      return {
        comments: state.comments,
      };
    };

    const mapDispatchToProps = (dispatch: any) => {
      const { firstRender } = bindActionCreators(actions, dispatch);
      return {
        firstRender,
      };
    };

    export default connect(mapStateToProps, mapDispatchToProps)(CommentsList);



Ответы (0 шт):