Как правильно добавить новый объект в значение поля с разбивкой по страницам в кэш Apollo?

#javascript #apollo #react-apollo

Вопрос:

У меня есть сложный объект/тип graphql, содержащий сложные поля, значение которых-данные разбиения на страницы. Одно из полей называется comments и содержит данные разбиения комментариев на страницы. Я хочу использовать этот optimistic-ui подход и вручную добавить новый комментарий, когда пользователь его создаст, в значение comments поля перед выполнением мутации сервера, и таким образом я ожидаю показать пользователю только что созданный комментарий во время выполнения мутации на сервере.

Мне действительно интересно, как лучше всего это сделать?

Я попытался вручную создать узел разбиения на страницы и поместить его в исходные узлы комментариев, однако я получил ошибку: Ошибка типа: Не удается добавить свойство 2, объект не расширяется Я попытался клонировать исходное значение комментариев, чтобы иметь возможность изменить его, но ничего не помогает как-то.

Поэтому я хотел бы каким-то образом заинтересовать вас, как я мог бы справиться с этой проблемой.

Я буду признателен за любую помощь/информацию

P.S. Вот примеры кода

Объект всей исходной статьи

 {
    "__typename": "Article",
    "id": "607559b181072e34ecf7af25",
    "createdAt": "2021-04-13T08:43:29.846Z",
    "liked": false,
    "likes": 0,
    "commentsThreadId": "607559b181072e34ecf7af24",
    "comments": {
        "__typename": "CommentsConnection",
        "totalCount": 2,
        "pageInfo": {
            "__typename": "PageInfo",
            "hasNextPage": false,
            "startCursor": "NjA3NTY4N2Y4MTA3MmUzNGVjZjdhZjI5",
            "endCursor": "NjA5ZTRlMmIyM2U5NmEzZGRjOTQwMTIz",
            "hasPreviousPage": false,
            "count": 2
        },
        "edges": [
            {
                "__typename": "CommentEdge",
                "node": {
                    "__typename": "Comment",
                    "id": "6075687f81072e34ecf7af29",
                    "text": "Comments like this are just amazing. YavatarImgUrlou can write whatever you want and after that, you can check the result of this. It can have more than 3 lines",
                    "liked": false,
                    "likes": 0,
                    "createdAt": "2021-04-13T09:46:39.806Z",
                    "owner": {
                        "__typename": "UserBase",
                        "id": "60658c4632aaea36205cffa2",
                        "firstName": "David",
                        "lastName": null,
                        "username": "david1",
                        "numericId": "3321"
                    }
                }
            },
            {
                "__typename": "CommentEdge",
                "node": {
                    "__typename": "Comment",
                    "id": "609e4e2b23e96a3ddc940123",
                    "text": "Some simple comment guys",
                    "liked": false,
                    "likes": 0,
                    "createdAt": "2021-05-14T10:17:15.057Z",
                    "owner": {
                        "__typename": "UserBase",
                        "id": "608156675ca92e56749d71fc",
                        "firstName": "Sviat",
                        "lastName": null,
                        "username": "sviat1",
                        "numericId": "9421"
                    }
                }
            }
        ]
    },
    "author": {
        "__typename": "User",
        "id": "60754dda81072e34ecf7af13",
        "imageUrl": null,
        "firstName": "John",
        "lastName": "Peterson",
        "username": "john1",
        "numericId": "3659"
    },
    "topics": [
        {
            "__typename": "Topic",
            "id": "60658c8c470f285c18652917",
            "name": "libsep"
        },
        {
            "__typename": "Topic",
            "id": "60658c89521b0e5c18daf3d6",
            "name": "huribu"
        }
    ]
}
 

Код, который я использовал для обновления comments поля

     const { getArticle: cachedArticle } = apolloClient.readQuery({
      query: GET_ARTICLE_QUERY,
      variables: {
        // Provide any required variables here
        id: article.id,
      },
    });
    
    const newComment = {
      __typename: "Comment",
      id: "6075687f81072e34ecf7af29",
      text: 'Shiny New Comment Text',
      liked: false,
      likes: 0,
      createdAt: "2021-04-13T09:46:39.806Z",
      owner: {
        __typename: "UserBase",
        id: "60658c4632aaea36205cffa2",
        firstName: "David",
        lastName: null,
        username: "david1",
        numericId: "3321",
      },
    };
    // Tried to create the new object that allowed to modify
    const newComments = { ...cachedArticle.comments };

    // got an error at this stage
    newComments.edges.push({
      __typename: "CommentEdge",
      node: newComment,
    });
 

Комментарии:

1. вам нужно заменить любой [подлежащий] изменению объект … newComments.edges = [...newComments.edges, {.....new edge ..}] — читайте о «неизменяемом»

2. Привет @xadm. Спасибо за ваше внимание. Вы правы, нам нужно использовать глубокое клонирование, чтобы быть уверенными, что наши новые объекты не будут ссылаться на старые. Я просто забываю этот нюанс)