React Apollo Client - 查询结果在缓存中混淆
React Apollo Client - query results mixing up in cache
我使用 apollo 客户端获取书籍图表并使用中继式分页。以下两个 NEW_BOOKS
查询和 ALL_BOOKS
查询都可以独立工作。
目前,我在主页中使用 NEW_BOOKS
,在主页的弹出窗口中使用 ALL_BOOKS
。
当主页打开时 NEW_BOOKS
加载正常。
当打开弹出窗口并获取 ALL_BOOKS
时,newBooks
变为 undefined
或 ALL_BOOKS
查询的结果。
为什么会这样?
const { loading, data: newBooks, fetchMore, networkStatus } = useQuery(NEW_BOOKS, {
variables: {
first: PAGE_SIZE,
after: endCursor
},
notifyOnNetworkStatusChange: true
});
const NEW_BOOKS = gql`query GetNewBooks($first:Int!, $after:String){
books(
first: $first, after: $after,
filters: [
{
path: "isNew",
value: true
}
]
) {
totalCount
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
node {
id
name
author {
id
name
}
}
}
}
}`;
-所有图书查询均可按名称过滤
const { loading, data: filteredBooks, fetchMore, networkStatus } = useQuery(ALL_BOOKS, {
variables: {
first: PAGE_SIZE,
after: endCursor,
name: nameFilter
},
notifyOnNetworkStatusChange: true
});
const ALL_BOOKS = gql`query GetAllBooks($first:Int!, $after:String, $name:String){
books(
first: $first, after: $after,
filters: [
{
path: "name",
value: $name,
type: "contains"
}
]
) {
totalCount
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
node {
id
name
copiesSold
author {
id
name
}
}
}
}
}`;
正在使用的缓存如下所示,
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
books: relayStylePagination(),
},
}
},
});
当使用 relayStylePagination
或类似的分页时,我们必须明确地传递 keyArgs
。
A keyArgs: ["type"] 字段策略配置意味着在访问该字段的值时,类型是缓存应该考虑的唯一参数(除了字段名称和封闭对象的标识之外)。一个 keyArgs: false 配置禁用了通过参数区分字段值的整个系统,因此字段的值将仅由字段的名称(在某些 StoreObject 中)标识,而不附加任何序列化参数。
KeyArgs documentation here.
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
books: relayStylePagination(["name"]),
},
}
},
});
我使用 apollo 客户端获取书籍图表并使用中继式分页。以下两个 NEW_BOOKS
查询和 ALL_BOOKS
查询都可以独立工作。
目前,我在主页中使用 NEW_BOOKS
,在主页的弹出窗口中使用 ALL_BOOKS
。
当主页打开时 NEW_BOOKS
加载正常。
当打开弹出窗口并获取 ALL_BOOKS
时,newBooks
变为 undefined
或 ALL_BOOKS
查询的结果。
为什么会这样?
const { loading, data: newBooks, fetchMore, networkStatus } = useQuery(NEW_BOOKS, {
variables: {
first: PAGE_SIZE,
after: endCursor
},
notifyOnNetworkStatusChange: true
});
const NEW_BOOKS = gql`query GetNewBooks($first:Int!, $after:String){
books(
first: $first, after: $after,
filters: [
{
path: "isNew",
value: true
}
]
) {
totalCount
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
node {
id
name
author {
id
name
}
}
}
}
}`;
-所有图书查询均可按名称过滤
const { loading, data: filteredBooks, fetchMore, networkStatus } = useQuery(ALL_BOOKS, {
variables: {
first: PAGE_SIZE,
after: endCursor,
name: nameFilter
},
notifyOnNetworkStatusChange: true
});
const ALL_BOOKS = gql`query GetAllBooks($first:Int!, $after:String, $name:String){
books(
first: $first, after: $after,
filters: [
{
path: "name",
value: $name,
type: "contains"
}
]
) {
totalCount
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
node {
id
name
copiesSold
author {
id
name
}
}
}
}
}`;
正在使用的缓存如下所示,
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
books: relayStylePagination(),
},
}
},
});
当使用 relayStylePagination
或类似的分页时,我们必须明确地传递 keyArgs
。
A keyArgs: ["type"] 字段策略配置意味着在访问该字段的值时,类型是缓存应该考虑的唯一参数(除了字段名称和封闭对象的标识之外)。一个 keyArgs: false 配置禁用了通过参数区分字段值的整个系统,因此字段的值将仅由字段的名称(在某些 StoreObject 中)标识,而不附加任何序列化参数。 KeyArgs documentation here.
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
books: relayStylePagination(["name"]),
},
}
},
});