问题描述:
在使用Apollo客户端的过程中,有时候使用writeQuery方法更新缓存数据,但并没有触发UI的更新。
代码示例:
import { useQuery, useApolloClient } from '@apollo/client';
import { gql } from 'apollo-boost';
const GET_USERS = gql`
query GetUsers {
users {
id
name
}
}
`;
const UPDATE_USER = gql`
mutation UpdateUser($id: ID!, $name: String!) {
updateUser(id: $id, name: $name) {
id
name
}
}
`;
const UserList = () => {
const client = useApolloClient();
const { loading, error, data } = useQuery(GET_USERS);
const handleUpdateUser = async (id, name) => {
await client.mutate({
mutation: UPDATE_USER,
variables: { id, name },
});
// 更新缓存数据
client.writeQuery({
query: GET_USERS,
data: {
users: data.users.map(user => {
if (user.id === id) {
return { ...user, name };
}
return user;
}),
},
});
};
if (loading) return Loading...
;
if (error) return Error :(
;
return (
{data.users.map(user => (
{user.name}
))}
);
};
解决方法:
在更新缓存数据后,需要手动触发UI更新。可以通过在writeQuery方法之后调用client.broadcastQueries()方法来实现。
修改UserList组件中的handleUpdateUser方法如下:
const handleUpdateUser = async (id, name) => {
await client.mutate({
mutation: UPDATE_USER,
variables: { id, name },
});
// 更新缓存数据
client.writeQuery({
query: GET_USERS,
data: {
users: data.users.map(user => {
if (user.id === id) {
return { ...user, name };
}
return user;
}),
},
});
// 触发UI更新
client.broadcastQueries();
};
这样就能保证缓存数据更新后,UI能够正确地进行更新了。