React-Apollo:带变量的查询导致 UI 不再乐观
React-Apollo: Query with variables causes the UI to no longer be optimistic
我正在使用 Apollo GraphQL(使用 React Apollo Hooks,但这没有区别)编写一个 React 组件。
这是我的查询:
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);
}
}
一旦我用 limit
注释掉 variables
键,UI 就不会再乐观地更新了。注释掉它的值。这里出了什么问题?
writeQuery
方法也接受 variables
值。 query
和 variables
的每个组合都被 Apollo 视为单独的查询。因此,如果一个 Query
组件(或挂钩)使用 100
的限制而另一个使用 50
的限制,则在编写 update
函数时,您需要调用writeQuery
对于这两个查询,每次都为 variables
传递不同的值:
cache.writeQuery({ query, data, variables: { limit: 100 } })
cache.writeQuery({ query, data, variables: { limit: 50 } })
这是 know limitation of the client. In effect, you need to keep track of the variables through local state in order to correctly call writeQuery
when your update
function is called. This can be, understandably, a huge hassle. Luckily, you can utilize apollo-link-watched-mutation 解决问题的方法。
我正在使用 Apollo GraphQL(使用 React Apollo Hooks,但这没有区别)编写一个 React 组件。
这是我的查询:
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);
}
}
一旦我用 limit
注释掉 variables
键,UI 就不会再乐观地更新了。注释掉它的值。这里出了什么问题?
writeQuery
方法也接受 variables
值。 query
和 variables
的每个组合都被 Apollo 视为单独的查询。因此,如果一个 Query
组件(或挂钩)使用 100
的限制而另一个使用 50
的限制,则在编写 update
函数时,您需要调用writeQuery
对于这两个查询,每次都为 variables
传递不同的值:
cache.writeQuery({ query, data, variables: { limit: 100 } })
cache.writeQuery({ query, data, variables: { limit: 50 } })
这是 know limitation of the client. In effect, you need to keep track of the variables through local state in order to correctly call writeQuery
when your update
function is called. This can be, understandably, a huge hassle. Luckily, you can utilize apollo-link-watched-mutation 解决问题的方法。