Apollo GraphQL updateQuery to typePolicy
Sep 01 2020
나는 벽에 머리를 치고있다. 나는 아폴로 3로 업데이트 한과를 마이그레이션하는 방법을 알아낼 수 없습니다 updateQueryA를 typePolicy. 기본 연속 기반 페이지 매김을 수행하고 있으며 다음과 같은 결과를 병합하는 데 사용되었습니다 fetchMore.
await fetchMore({
query: MessagesByThreadIDQuery,
variables: {
threadId: threadId,
limit: Configuration.MessagePageSize,
continuation: token
},
updateQuery: (prev, curr) => {
// Extract our updated message page.
const last = prev.messagesByThreadId.messages ?? []
const next = curr.fetchMoreResult?.messagesByThreadId.messages ?? []
return {
messagesByThreadId: {
__typename: 'MessagesContinuation',
messages: [...last, ...next],
continuation: curr.fetchMoreResult?.messagesByThreadId.continuation
}
}
}
merge typePolicy나 자신 을 작성하려고 시도 했지만 Apollo 캐시에 중복 식별자에 대한 오류가 계속로드되고 발생합니다. 여기 내 것입니다 typePolicy외모는 내 쿼리에 대해 좋아합니다.
typePolicies: {
Query: {
fields: {
messagesByThreadId: {
keyArgs: false,
merge: (existing, incoming, args): IMessagesContinuation => {
const typedExisting: IMessagesContinuation | undefined = existing
const typedIncoming: IMessagesContinuation | undefined = incoming
const existingMessages = (typedExisting?.messages ?? [])
const incomingMessages = (typedIncoming?.messages ?? [])
const result = existing ? {
__typename: 'MessageContinuation',
messages: [...existingMessages, ...incomingMessages],
continuation: typedIncoming?.continuation
} : incoming
return result
}
}
}
}
}
답변
DylanVester Sep 15 2020 at 14:21
그래서 제 사용 사례를 해결할 수있었습니다. 실제로 필요한 것보다 훨씬 더 어려워 보입니다. 기본적으로 들어오는 항목과 일치하는 기존 항목을 찾아 덮어 쓰고 캐시에 아직없는 새 항목을 추가해야합니다.
또한 연속 토큰이 제공된 경우에만이 논리를 적용해야합니다. null이거나 정의되지 않은 경우 초기로드를 수행하고 있음을 나타 내기 때문에 들어오는 값을 사용해야하기 때문입니다.
내 문서는 다음과 같은 모양입니다.
{
"items": [{ id: string, ...others }],
"continuation": "some_token_value"
}
모양이 비슷한 모든 문서에 사용할 수있는 일반 유형 정책을 만들었습니다. 항목 속성의 이름, 캐시하려는 주요 인수 및 graphql 유형의 이름을 지정할 수 있습니다.
export function ContinuationPolicy(keyArgs: Array<string>, itemPropertyKey: string, typeName: string) {
return {
keyArgs,
merge(existing: any, incoming: any, args: any) {
if (!!existing && !!args.args?.continuation) {
const existingItems = (existing ? existing[itemPropertyKey] : [])
const incomingItems = (incoming ? incoming[itemPropertyKey] : [])
let items: Array<any> = [...existingItems]
for (let i = 0; i < incomingItems.length; i++) {
const current = incomingItems[i] as any
const found = items.findIndex(m => m.__ref === current.__ref)
if (found > -1) {
items[found] === current
} else {
items = [...items, current]
}
}
// This new data is a continuation of the last data.
return {
__typename: typeName,
[itemPropertyKey]: items,
continuation: incoming.continuation
}
} else {
// When we have no existing data in the cache, we'll just use the incoming data.
return incoming
}
}
}
}