我正在尝试使用
cache.modify
来更新突变后的字段。这是我的 reactions
模型的 Message
字段。该突变消除了 reactions
场的反应。我正在使用乐观的反应。
奇怪的是,当获得后端响应第二次触发时,
update
会以未修改的缓存被调用。
这是一个小代码示例(
removeReactionMutation
是useMutation
钩子返回的突变函数):
const { data } = await removeReactionMutation({
variables,
optimisticResponse,
update: ((cache, options) => {
const { data } = options;
console.log('update called', options);
console.log(
'optimistic cache',
JSON.stringify(
cache.extract(true)[GUID2ACID(variables.messageId)].reactions
)
);
console.log(
'real cache',
JSON.stringify(
cache.extract()[GUID2ACID(variables.messageId)].reactions
)
);
cache.modify({
id: GUID2ACID(variables.messageId),
fields: {
reactions(existing) {
console.log('removing reaction', {
existing,
userId: identity.guid,
emojiId: variables.emojiId,
});
return existing.filter(
(reaction: IAPIMessageReaction) =>
reaction.userId !== identity.guid ||
reaction.emojiId !== variables.emojiId
);
},
},
optimistic: true, // this flag seems to have no effect
});
console.log(
'optimistic cache',
JSON.stringify(
cache.extract(true)[GUID2ACID(variables.messageId)].reactions
)
);
console.log(
'real cache',
JSON.stringify(
cache.extract()[GUID2ACID(variables.messageId)].reactions
)
);
}),
});
这是
console.log
输出:
useEmojis.ts:163 update called {data: {…}} <----- called with optimistic response
useEmojis.ts:164 optimistic cache [... 5 records]
useEmojis.ts:170 real cache [...5 records]
useEmojis.ts:195 removing reaction {existing: Array(5), userId: '...', emojiId: '...'}
useEmojis.ts:210 optimistic cache [...4 records]
useEmojis.ts:216 real cache [...4 records]
useEmojis.ts:163 update called {data: {…}} <----- called with backend response
useEmojis.ts:164 optimistic cache [... 5 records] <----- WHY!?
useEmojis.ts:170 real cache [... 5 records] <----- WHY!?
useEmojis.ts:195 removing reaction {existing: Array(5), userId: '...', emojiId: '...'}
useEmojis.ts:210 optimistic cache [... 4 records]
useEmojis.ts:216 real cache [... 4 records]
因此,在第一次
update
调用期间,该项目被 cache.modify
(乐观层和主层)从缓存中删除。 UI 已正确更新,并且反应已消除。到目前为止一切顺利!
但是,该项目仍然存在于缓存中,并且在获得服务器响应后第二次调用
existing
回调时的 update
值!
这非常令人困惑并且会导致问题。
如果
update
被快速调用多次,然后随着服务器响应一一传入,又被多次调用,过时的缓存和 existing
值会导致已删除的项目暂时重新出现在在它们最终被删除之前的 UI。
这是因为您有两个待处理的
cache.modify
电话。两个调用都会删除自己的项目,但由于第一个调用获取现有值,而另一个项目错误地出现在数组中,因此该项目将在第一个 cache.modify
调用后在 UI 中重新出现一段时间。第一次调用不会删除它(这是预期的),并且另一个项目会显示,直到第二次调用最终删除它。我希望这是有道理的。
所以最后你需要一些外部逻辑来保存所有应该删除的项目并过滤
existing
,以便所有要删除的项目都从existing
值中排除。需要有这样的外部逻辑感觉不太对。
另外,我尝试使用
cache.modify
标志打开/关闭来调用 optimistic
,但在任何一种情况下,两个缓存层都被修改,因此不清楚该标志的含义。
我的问题是为什么在
update
回调的第二次调用期间,缓存再次在两层中保存已删除的项目?
换句话说,缓存在第二次
update
调用期间处于未修改状态,这不是 UI atm 中呈现的内容。这是我无法理解的事情,我很感激这里的任何帮助或想法。
好吧,我明白了...
这并不神秘,缓存会因为实时订阅而更新。所以它发生在突变
update
回调之外。在回调运行之间,由于实时订阅消息的传入,缓存会被修改。
我将为可能遇到类似问题的任何人保留这个答案。您很可能需要寻找其他可以更新缓存的地方。