在更新用作全局存储的Apollo缓存时如何分离逻辑?

问题描述 投票:1回答:1

将Apollo缓存用作全局存储-远程和本地数据非常方便。

但是,尽管我从未使用过redux,但我认为最重要的是实现流量:前端中的事件驱动架构,该架构将逻辑分离并确保关注点分离。

我不知道如何用Apollo来实现。医生说

[当变异修改多个实体时,或者如果它创建或删除实体,则Apollo客户端缓存不会自动更新以反映变异的结果。要解决此问题,您对useMutation的调用可以包含更新功能。

在处理所有缓存更新的应用程序的一部分中添加update函数;通过更新应用程序所有其他部分的查询和/或片段,这正是我们希望在Flux中避免的事情 /事件驱动的体系结构。

为了说明这一点,让我举一个简单的例子。在这里,我们有(至少3个链接的组件)

1。 InboxCountSideNav

中显示收件箱项目数的组件
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

有人对实现更多独立组件有建议吗?我创建查询的方式有问题吗?

graphql react-apollo apollo-client flux
1个回答
1
投票

关于update的不幸事实是,它以简单换取了性能。一个真正的“哑巴”客户端只会从服务器接收数据并进行渲染,而不会对其进行操作。通过指示Apollo在突变后如何修改缓存,我们不可避免地复制了服务器上已经存在的业务逻辑。避免这种情况的唯一方法是:

  • 让突变返回图形的较大部分。例如,如果用户创建了一个帖子,而不是返回创建的帖子,则返回完整的用户对象,包括该用户的所有帖子。
  • 重新获得受影响的查询。
  • 当然,通常两种方法都不是特别理想的,我们选择将业务逻辑注入客户端应用程序。

分隔此业务逻辑可能很简单,只需将更新功能保存在单独的文件中,然后根据需要导入它们。这样,至少您可以单独测试更新逻辑。您可能还希望使用链接之类的更优雅的解决方案。 apollo-link-watched-mutation是链接的一个很好的例子,它使您可以将update逻辑与组件分开。它还解决了必须跟踪查询变量才能执行这些更新的问题。

© www.soinside.com 2019 - 2024. All rights reserved.