#reactjs #apollo-client #react-apollo #apollo-cache-inmemory
#reactjs #apollo-client #реагировать-apollo #apollo-cache-inmemory
Вопрос:
У меня есть два простых запроса:
query GerMenuA {
menus {
menuA {
items {
label
}
}
}
}
query GerMenuB {
menus {
menuB {
items {
label
}
}
}
}
Но в консоли я вижу предупреждение:
Cache data may be lost when replacing the menus field of a Query object.
existing: {"__typename":"Menu","menuA":[{...}]}
incoming: {"__typename":"Menu","menuB":[{...}]}
Есть ли способ просто не объединять их и удалить предупреждение? Потому что, если указать в typePolicies
Menu: { merge: true }
or
Menu: { merge: false }
это не то, что я хочу, потому что это разные данные, и эти две очереди не нужно каким-либо образом объединять. Кроме того, у меня нет id
поля и keyFields
оно не будет работать в этом случае, потому что метки могут быть одинаковыми для обоих меню
Ответ №1:
Итак, на ваш вопрос трудно ответить без ваших определений типов схемы. Но давайте предположим, что это что-то вроде этого:
type Query {
menus: Menus
}
type Menus {
menuA: Menu
menuB: Menu
}
В предупреждении, по сути, говорится, что без какого-либо keyArgs
Apollo Cache невозможно нормализовать menus
запрос. Имейте в виду, с их точки зрения — у вас один menus
корневой запрос. (т. Е. GerMenuA
GerMenuB
Запросы на стороне клиента, а не корневые запросы).
(Примечание — поскольку у вас нет id
полей, см. раздел Отключение нормализации.)
Вариант 1: разделите ваши запросы
type Query {
menuA: Menu
menuB: Menu
}
Кэш Apollo теперь будет хранить menuA
и menuB
как отдельные запросы. Если вы хотите быть в безопасности, вы можете установить свои политики типов:
const createCache = () => new InMemoryCache({
typePolicies: {
Menu: {
keyFields: false
},
Query: {
fields: {
menuA: {
keyArgs: false
},
menuB: {
keyArgs: false
}
}
}
},
});
keyFields: false
сообщает AC о сохранении Menu
в соответствии с его родительским запросом. keyArgs: false
говорит, что оба menuA
и menuB
являются одноэлементными запросами. Политика кэша по умолчанию будет merge: false
такой, чтобы существующие данные были заменены входящими.
Вариант 2: определить параметр запроса
В этом случае вы добавляете name
параметр в свой menus
запрос:
type Query {
menus(name: String): Menu
}
По умолчанию кэш хранит отдельное значение для каждой уникальной комбинации значений аргументов, которые вы предоставляете при запросе определенного поля.
Кэш Apollo теперь будет хранить menus:{name:menuA}
и menus:{name:menuB}
как отдельные объекты кэша. Опять же, если вы хотите быть в безопасности, вы можете установить свои политики типов:
const createCache = () => new InMemoryCache({
typePolicies: {
Menu: {
keyFields: false
}
},
});
Опять же, политика кэша по умолчанию будет merge: false
такой, чтобы существующие данные были заменены входящими.
Вариант 3: определение политики слияния
Мы рассмотрели, почему существующая схема сбивает с толку Apollo Cache. Но если вы действительно настроены на это, осталось определить политику слияния:
const createCache = () => new InMemoryCache({
typePolicies: {
Menu: {
keyFields: false
},
Menus: {
keyFields: false,
merge: true
},
Query: {
fields: {
menus: {
keyArgs: false,
merge: true
}
}
}
},
});
merge: true
сообщает Apollo Cache объединить результаты GerMenuA
и GerMenuB
в один Menus
объект кэша с обоими menuA
menuB
свойствами и . Без этого при каждом запуске запроса вы бы уничтожали результаты предыдущего запроса.