是否可以在 Apollo Client 中用新 id 更新或替换缓存条目的 id?

Posted

技术标签:

【中文标题】是否可以在 Apollo Client 中用新 id 更新或替换缓存条目的 id?【英文标题】:Is it possible to update or replace a cached entry's id with a new id in Apollo Client? 【发布时间】:2022-01-08 19:48:00 【问题描述】:

所以我的应用中有一个station。这是一个示例对象:

interface Station 
  id: number; // auto-increment
  stationId: number; // this is a constant
  name: string;
  status: 'live' | 'draft';

更新station 时,stationId 永远不会改变,但 sql 会自动增加 id 字段。电台的status也将更新为'draft'。例如

const previousStation: Station = 
  id: 1,
  stationId: 123456,
  name: 'Example splet right',
  status: 'live',


// ... then some sql-fu

const nextStation: Station = 
  id: 2,
  stationId: 123456,
  name: 'Example spelt right',
  status: 'draft',

Apollo 客户端无法推断nextStation 应该替换previousStation,因此有很多突变需要readQuery/readFragment。

我希望可能有一个更简单的解决方案,但复杂性来自id 的更改。如果我可以在规范化数据缓存中找到对其对象 ID 的所有引用并更新这些字段。这样的事情有可能吗?

【问题讨论】:

【参考方案1】:

解决了。关键是使用读/写片段,使用旧的object-id,但传入新的 id 作为参考。然后从缓存中逐出旧引用。它看起来像这样:

mutation(
    variables,

    update(cache,  data ) 
        if (!data) 
            return;
        

        const  id: newId, __typename  = data.station;

        const existing = cache.readQuery(
            query: GET_STATION_QUERY,
            variables:  id: variables.id 
        );

        if (existing) 
            const newStation = 
                ...(existing.getStation || ),
                ...(data.updateStation || )
            ;

            cache.writeQuery(
                query: GET_STATION_QUERY,
                variables:  id: newId ,
                data:  station: newStation 
            );
        

        const oldObjectId = `$__typename:$variables.id`;

        const fragment = gql`
            fragment MyFragment on SomeType 
                station 
                    id
                
            
        `;

        const existingStationOnMyType = cache.readFragment(
            id: oldObjectId,
            fragment
        );

        if (existingStationOnMyType) 
            cache.writeFragment(
                id: oldObjectId,
                fragment,
                data: 
                    id: newId
                
            );

            cache.evict( id: oldObjectId );
            cache.gc();
        
    
);

【讨论】:

以上是关于是否可以在 Apollo Client 中用新 id 更新或替换缓存条目的 id?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo Client 2:来自 Mutation 的新对象:更新所有缓存的查询,这个新对象应该是其中的一部分? [复制]

是否可以使用 apollo-client 跳过部分查询

是否有与 Apollo 的 ReactNativeFile 等效的 URQL(来自 apollo-upload-client)?

Apollo 客户端递归突变

我可以将 useSWR 与 apollo-client 一起使用吗?

apollo-client 没有响应的标头