React-Apollo: запрос с переменными приводит к тому, что пользовательский интерфейс перестает быть оптимистичным
Я пишу компонент React с использованием Apollo GraphQL (с 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
ключ с limit
пользовательский интерфейс больше не обновляется оптимистично. С закомментированным значением это делает. Что здесь не так?
1 ответ
writeQuery
Метод также принимает variables
значение. Каждая комбинация query
а также variables
Аполлон рассматривается как отдельный запрос. Так что если один Query
Компонент (или хук) использует ограничение 100
а другой использует ограничение 50
при написании update
функция, вам нужно позвонить writeQuery
для обоих этих запросов, передавая другое значение для variables
каждый раз:
cache.writeQuery({ query, data, variables: { limit: 100 } })
cache.writeQuery({ query, data, variables: { limit: 50 } })
Это известное ограничение клиента. По сути, вам нужно отслеживать переменные через локальное состояние, чтобы правильно вызвать writeQuery
Когда ваш update
функция называется. Понятно, что это может быть огромной проблемой. К счастью, вы можете использовать https://github.com/haytko/apollo-link-watched-mutation, чтобы обойти эту проблему.