Проблема с понижением или повышением рейтинга с оптимистичным интерфейсом Apollo - PullRequest
0 голосов
/ 20 сентября 2019

Я недавно начал изучать программирование и только начал изучать базу данных.Сейчас я работаю над забавным приложением для меня и моих друзей.Человек просто посылает шутку, а другие оценивают ее.

Для внешнего интерфейса я использую React.js, Apollo Client.Для серверной части GraphQL и Prisma.

Сейчас у меня действительно проблемы с оптимистичным интерфейсом Apollo.Когда пользователь не проголосовал за шутку, проголосуйте за нее ИЛИ, если он уже проголосовал, затем «отмените голосование», пользовательский интерфейс обновляется правильно.Проблема возникает, когда пользователь меняет голосование, данные бэкэнда верны, но данные пользовательского интерфейса неверны.

Вот мои настройки внешнего интерфейса:

<Mutation
    mutation={CREATE_COMMENT_VOTE_MUTATION}
    variables={{ comment: id, type }},
    optimisticResponse: {
      __typename: 'Mutation',
      createCommentVote: {
        id: Math.round(Math.random() * -100000000),
        type: 'UPVOTE',
        user: { id: currentUser.id, __typename: 'User' },
        __typename: 'CommentVote',
      },
    },
    update: {(proxy, { data: { createCommentVote: createVote } }) => {
    const {
      videoId,
      comment: { id },
      currentUser,
    } = this.props;
    // Read the data from our cache for this query.
    const data = proxy.readQuery({
      query: QUERY_VIDEO_COMMENTS,
      variables: { video: videoId },
    });
    // Find the joke that's being voted on
    const votingJoke = data.jokes.find(joke => joke.id === JokeId);
    // Finding the vote of user in the joke's votes
    const existingVote =
      votingJoke.vote.length > 0
        ? votingJoke.vote.find(vote => vote.user.id === currentUser.id)
        : null;
    data.jokes = data.jokes.map(joke => {
      if (joke.id === id) {
        if (!existingVote) {
        // User hasn't voted on the joke
          joke.vote = joke.vote.concat([createVote]);
        } else if (existingVote && existingVote.type !== createVote.type) {
          // If the previous vote is different from new vote, update old value
          joke.vote = joke.vote.map(jokeVote => {
            if (jokeVote.user.id === currentUser.id) {
              jokeVote.type = createVote.type
            }
            return jokeVote;
          });
        } else if (existingVote && existingVote.type === createVote.type) {
          // Unvote
          joke.vote = joke.vote.filter(
            jokeVote => jokeVote.user.id !== currentUser.id
          );
        }
      }
      return comment;
    });
    proxy.writeQuery({
      query: QUERY_VIDEO_COMMENTS,
      variables: { video: videoId },
      data,
    });
  };},
  >

Я попытался войти в существующий голос,createVote, шутки голосуют массив до и после.

При новом голосовании все в порядке: NewVote

Также отлично работает на unvote: Unvote

При изменении голосования логика хорошо обрабатывала фиктивные данные, но путала ответ: При изменении голосования

Вот модель данных:

type Joke {
  id: ID! @id
  author: User! @relation(name: "CommentToUser")
  vote: [CommentVote]!
    @relation(name: "CommentVoteToComment", onDelete: CASCADE)
  text: String!
  createdAt: DateTime! @createdAt
  updatedAt: DateTime! @updatedAt
}

type CommentVote {
  id: ID! @id
  user: User! @relation(name: "CommentVoteToUser")
  joke: Comment! @relation(name: "CommentVoteToComment")
  createdAt: DateTime! @createdAt
  type: VoteType!
}

enum VoteType {
  UPVOTE
  DOWNVOTE
}
...