如果如果要更新的查询尚未运行并已缓存(即在页面重新加载后),我如何安全地更新Apollo客户端缓存?
Apollo文档不清楚如何更新(安全或不安全)从未运行过的缓存查询(因此没有要修改的缓存数据)。尝试在没有缓存数据的查询上使用writeQuery
会引发错误,显然不会更新查询。
try...catch
期间使用writeQuery
我目前唯一的想法是围绕不同的查询更新调用try...catch
,但这似乎是额外的工作。不仅如此,我还是可能会忽略与已经存在的查询无关的实际错误。
我有两个组件,一个用于列出用户的个人消息,另一个用于用户草稿列表。即使所有草稿也个人消息,但我使用两个不同的查询来提高效率,因为用户可能总是比发送的消息少得多。
正常使用应用程序时(例如,在导航时加载所有查询)一切正常。要创建草稿,我需要转到Drafts.jsx
(加载草稿查询,重要!)并单击按钮创建草稿。在创建草稿时,我运行下面看到的update
函数(需要更新两个查询,因为它们的内部参数不同)。 “草稿”查询的缓存更新按预期工作,因为查询已经执行并且数据存储在缓存中。但是,由于我从未访问过MyMessages页面,因此“MyMessages”查询失败并引发错误。
我的消息查询(在MyMessages.jsx
)
const RECEIVED_MESSAGES_QUERY = gql`
query GetGroup($groupSlug: String!) {
groupEdge(groupSlug: $groupSlug) {
node {
id
name
slug
allMessages(author: true) {
edges {
node {
id
status
subject
preview
}
}
}
}
}
}
`;
草稿查询(在Drafts.jsx
中):
const DRAFT_MESSAGES_QUERY = gql`
query GetGroup($groupSlug: String!) {
groupEdge(groupSlug: $groupSlug) {
node {
id
name
slug
allMessages(author: true, includeStatus: ["draft"]) {
edges {
node {
id
status
subject
preview
}
}
}
}
}
}
`;
突变(CreateDraft.jsx
):
// Mutation file
const draftsData = proxy.readQuery({
query: MemberDraftsQuery,
variables: { groupSlug },
});
console.log('draftsData', draftsData);
// NOTE: Fails here (doesn't progress to next console statement)
const messagesData = proxy.readQuery({
query: MemberMessagesQuery,
variables: { groupSlug },
});
console.log('messagesData', messagesData);
// Add the new draft edge to the member's drafts
draftsData.groupEdge.node.allMessages.edges.push(createdDraftEdge);
// Add the new draft edge to the member's authored messages (uses different query)
messagesData.groupEdge.node.allMessages.edges.push(createdDraftEdge);
proxy.writeQuery({
query: MemberDraftsQuery,
data: draftsData,
variables: { groupSlug },
});
proxy.writeQuery({
query: MemberMessagesQuery,
data: messagesData,
variables: { groupSlug },
});
StackOverflow - How to update apollo cache after mutation query with filter
这篇文章涉及与我相同的方面,但我已经处理variables
中的writeQuery
。但是,这是否意味着我应该try...catch
进行每次writeQuery
操作?如果由于其他原因失败怎么办?总而言之,不确定它是否回答了我的问题。
经过一些更多的编码(并在下面的评论中看到),我意识到readQuery
导致了问题(不是writeQuery
)。由于我不喜欢使用try...catch
,因为它会混淆错误而不知道导致错误的原因,因此我更新了我的方法,使try...catch
只处理readQuery
错误。如果在此处抛出错误,我假设查询不存在(应单独处理)或缓存数据不存在。在这两种情况下,我只是跳过写入该查询。
import { MemberDraftsQuery } from '@componens/MemberDrafts';
...
class MemberDraftDetails extends Component {
onSubmit = (groupSlug) => {
mutate({
variables: {
input: {
content,
subject,
...
}
},
update: (proxy, { data: responseData }) => {
const draftEdge = responseData.createDraft;
// UNUSED: Could be used to validate the query actually exists (doesn't warn for some reason)
const hasDraftsQuery = Boolean(MemberDraftsQuery);
let hasDraftsQueryCache = true;
// A failure to read the query means that there is no cached data (therefore cannot read/write)
// NOTE: Could write default data, but no reason to (since it will be fetched later)
try {
const draftsData = proxy.readQuery({
query: MemberDraftsQuery,
variables: { groupSlug },
});
} catch (e) {
hasDraftsQueryCache = false;
}
// Only add the draft to the cache if it exists. If not, it will be queried and retrieved later
if (hasDraftsQueryCache) {
const newDraftEdges = data.groupEdge.node.allMessages.edges.concat(draftEdge);
data.groupEdge.node.allMessages.edges = newDraftEdges;
proxy.writeQuery({
query: MemberDraftsQuery,
data,
variables: { groupSlug },
});
}
}
}).then().catch();
}
}