将Apollo缓存用作全局存储-远程和本地数据非常方便。
但是,尽管我从未使用过redux,但我认为最重要的是实现流量:前端中的事件驱动架构,该架构将逻辑分离并确保关注点分离。
我不知道如何用Apollo来实现。医生说
[当变异修改多个实体时,或者如果它创建或删除实体,则Apollo客户端缓存不会自动更新以反映变异的结果。要解决此问题,您对useMutation的调用可以包含更新功能。
在处理所有缓存更新的应用程序的一部分中添加update
函数;通过更新应用程序所有其他部分的查询和/或片段,这正是我们希望在Flux中避免的事情 /事件驱动的体系结构。
为了说明这一点,让我举一个简单的例子。在这里,我们有(至少3个链接的组件)
1。 InboxCount在SideNav
query getInboxCount {
inbox {
id
count
}
}
2。收件箱列表项在“收件箱”页面中显示项目的组件
query getInbox {
inbox {
id
items {
...ItemPreview
...ItemDetail
}
}
}
这两个组件read来自自动生成的钩子的那些GQL查询中的数据,即const { data, loading } = useGetInboxItemsQuery()
3。 AddItem创建新项目的组件。因为它creates一个新实体,所以我需要手动更新cache
。所以我被迫写
(伪代码)
const [addItem, { loading }] = useCreateItemMutation({
update(cache, { data }) {
const cachedData = cache.readQuery<GetInboxItemsQuery>({
query: GetInboxItemsDocument,
})
if (cachedData?.inbox) {
// 1. Update items list GetInboxItemsQuery
const newItems = cachedData.inbox.items.concat(data.items)
cache.writeQuery({
query: GetInboxItemsDocument,
data: {
inbox: {
id: 'me',
__typename: 'Inbox',
items: newItems,
},
},
})
// 2. Update another query wrapped into another reusable method, here
setInboxCount(cache, newItems.length)
}
},
})
在这里,我的AddItem
组件必须是在我的应用程序中声明的其他不同查询/片段的aware😭此外,由于它很冗长,因此update
方法的复杂性正在迅速增加。特别是当多个列表/查询应更新,例如here
有人对实现更多独立组件有建议吗?我创建查询的方式有问题吗?
关于update
的不幸事实是,它以简单换取了性能。一个真正的“哑巴”客户端只会从服务器接收数据并进行渲染,而不会对其进行操作。通过指示Apollo在突变后如何修改缓存,我们不可避免地复制了服务器上已经存在的业务逻辑。避免这种情况的唯一方法是:
当然,通常两种方法都不是特别理想的,我们选择将业务逻辑注入客户端应用程序。
分隔此业务逻辑可能很简单,只需将更新功能保存在单独的文件中,然后根据需要导入它们。这样,至少您可以单独测试更新逻辑。您可能还希望使用链接之类的更优雅的解决方案。 apollo-link-watched-mutation是链接的一个很好的例子,它使您可以将update
逻辑与组件分开。它还解决了必须跟踪查询变量才能执行这些更新的问题。