我最近开始学习编程,然后才开始进入数据库。现在,我正在为我和我的朋友开发一个有趣的应用程序。一个人只是开玩笑,而其他人则对它开玩笑。
对于前端,我使用的是React.js,Apollo Client。对于后端GraphQL和Prisma。
现在,我在Apollo的Optimistic UI方面确实遇到了麻烦。如果用户尚未对笑话进行投票,然后对其进行投票,或者如果用户已对该笑话进行投票,则对其“投票”,则UI会正确更新。当用户更改投票,后端数据正确但UI数据错误时,就会出现问题。
这是我的前端突变设置:
<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
更改投票时,逻辑可以很好地处理虚拟数据,但会弄乱响应:On Vote Change
这是数据模型:
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
}