reactjs - React-Apollo:带变量的查询导致 UI 不再乐观
问题描述
我正在使用 Apollo GraphQL 编写一个 React 组件(使用 React Apollo Hooks,但这没有区别)。
这是我的查询:
const { data, error, loading } = useQuery(ListContacts, {
fetchPolicy: 'cache-and-network'
// variables: { limit: 1000 }
});
这是我进行突变的函数:
const createContact = useMutation(gql(mutations.createContact));
const deleteContact = useMutation(gql(mutations.deleteContact));
const updateContact = useMutation(gql(mutations.updateContact));
async function handleContactSave(contact) {
const isEmpty = allStringFieldsAreEmptyFromContact(contact);
const { id, ...processedContact } = replaceEmptyStringsWithNull(contact);
const idIsInArray = includesContactWithId(id)(contacts);
try {
if (isEmpty) {
if (idIsInArray) {
await deleteContact({
variables: { input: { id } },
optimisticResponse: () => ({ deleteContact: { id } }),
update: (cache, { data: { deleteContact } }) => {
const query = ListContacts;
const data = cache.readQuery({ query });
data.listContacts.items = data.listContacts.items.filter(
item => item.id !== deleteContact.id
);
cache.writeQuery({ query, data });
}
});
}
} else {
if (idIsInArray) {
await updateContact({
variables: { input: { id, ...processedContact } },
optimisticResponse: () => ({
updateContact: { __typename: 'Contact', id, ...processedContact }
}),
update: (cache, { data: { updateContact } }) => {
const query = ListContacts;
const data = cache.readQuery({ query });
data.listContacts.items = [
...data.listContacts.items.filter(
item => item.id !== updateContact.id
),
updateContact
];
cache.writeQuery({ query, data });
}
});
} else {
await createContact({
variables: { input: { ...processedContact } },
optimisticResponse: () => ({
createContact: {
__typename: 'Contact',
id: uuid(),
...processedContact
}
}),
update: (cache, { data: { createContact } }) => {
const query = ListContacts;
const data = cache.readQuery({ query });
data.listContacts.items = [
...data.listContacts.items.filter(
item => item.id !== createContact.id
),
createContact
];
cache.writeQuery({ query, data });
}
});
}
}
} catch (error) {
console.log(error);
}
}
一旦我variables
用 UI 注释掉键,limit
就不会再乐观地更新。注释掉它的值。这里出了什么问题?
解决方案
该writeQuery
方法还接受一个variables
值。query
Apollo 将和的每个组合variables
视为一个单独的查询。因此,如果一个Query
组件(或钩子)使用限制,100
而另一个使用限制50
,则在编写update
函数时,您需要调用writeQuery
这两个查询,variables
每次传入不同的值:
cache.writeQuery({ query, data, variables: { limit: 100 } })
cache.writeQuery({ query, data, variables: { limit: 50 } })
这是客户端的已知限制。实际上,您需要通过本地状态跟踪变量,以便在调用函数writeQuery
时正确调用。update
可以理解,这可能是一个巨大的麻烦。幸运的是,您可以利用apollo-link-watched-mutation来解决这个问题。
推荐阅读
- node.js - 反应中的状态没有得到更新
- c# - 为什么在此函数中忽略以下行?
- inheritance - 实例化子类型之前的 Julia Subtyp 验证
- php - Laravel 8:我可以创建 Eloquent 范围但不是针对查询构建器而是针对相关模型?
- python - 根据条件将列值与列中的值相除
- regex - 正则表达式匹配 CSS var
- android - 在 ubuntu 20.04 中构建 Android Alexa Auto SDK 3.2.1
- c# - 如何在 .NET 5 控制台应用程序中正确设置配置?
- javascript - 复制并粘贴带有已填充表单字段的图章,而没有弹出框提示我每次在 adobe 中完成填写的字段?
- c# - 对于在 C# 中生成的文件,Excel 无法计算状态栏中的总和