代码之家  ›  专栏  ›  技术社区  ›  lolo.io

从不同的请求字段读取缓存

  •  0
  • lolo.io  · 技术社区  · 4 年前

    使用React Native和Apollo客户端,我正在尝试从不同的请求字段正确地写入和读取缓存。 我基本上有两种对象类型:“用户”和“事件”,我有这些“请求:

    所有事件:(事件列表屏幕)

    events {
        id
        numberOfParticipants
    }
    

    将用户与他注册的事件连接起来:(议程屏幕)

    me {
        id
        myEvents {
            id
        }
    }
    

    用户注册到事件的突变:(事件详细信息屏幕)

    mutation {
        registerToAnEvent (id: number) {
            event {
                id
                numberOfParticipants
            }
        }
    

    当用户通过调用突变来注册事件时:

    我已经做了什么: 缓存被更新,事件列表屏幕数据立即受到影响。(参与者数量发生变化)

    我现在想要实现的目标: 我想立即从缓存修改中影响议程屏幕。无论出于什么原因,我都必须调用refetch来更新它。(当用户注册/注销时,事件应该从列表中消失或出现)

    以下是我的InMomoryCache实现的一些代码:

    Query: {
      fields: {
        event: {
          read(_, {args, toReference}) {
            return toReference({
              __typename: 'Event',
              id: args.id,
            });
          },
        },
        events: {
          keyArgs: false,
          merge(existing: any[], incoming: any[], allArgs) {
            const events: any[] = existing ? Object.values({...existing}) : [];
            const newEvents = incoming ? incoming : [];
            newEvents.forEach((event: any) => {
              events.push(event);
            });
            return events;
          },
        },
    },
    User: {
      fields: {
        eventsParticipating: {
          merge(existing: any[], incoming: any[], allArgs) {
            const events: any[] = existing ? Object.values({...existing}) : [];
            const newEvents = incoming ? incoming : [];
            newEvents.forEach((event: any) => {
              events.push(event);
            });
            return events;
          },
        },
    },
    

    感谢您的帮助:)

    0 回复  |  直到 4 年前
        1
  •  1
  •   lolo.io    4 年前

    我设法做到了。事实上,我不得不使用mutation的更新功能,因为实际上对象在缓存中被修改了,但返回用户事件列表的查询没有重新执行,所以它保持了相同数量的引用。

    如果突变返回的事件中的成员列表包含经过身份验证的用户,请将该ref添加到缓存的列表中。(如果您的对象没有被缓存,您可能需要使用writeFragment(即new comment))。

    否则从数组中删除该引用。

    https://www.apollographql.com/docs/react/caching/cache-interaction/

    cache.identify()返回以下形式的结果: <__tymename>:<id>

    Ref很容易被欺骗 { __ref: <reference> }

    此外,modify()函数获取的id如下所示: <__tymename>:&书信电报;id> (如果要以特定对象为目标)。

    我认为最好使用cache.identify()作为modify()的id,但在这种特殊情况下,它为我返回了undefined。

    这是我的代码:

    const [
    setParticipation,
    {data: dataParticipation, loading: loadingParticipation},
    ] = useMutation(setParticipationMutation, {
        update(cache, result) {
          cache.modify({
            id: 'User:' + user.id,
            fields: {
              eventsParticipating(events = []) {
                const ref = cache.identify(result.data.eventsParticipating);
                if (
                  result.data.eventsParticipating.members.filter(
                    m => m.id == user.id,
                  ).length > 0
                ) {
                  return [...events, {__ref: ref}]; // remove ref from array
                } else {
                  return events.filter(e => e.__ref != ref); // add ref to array
                }
              },
            },
          });
        },
      });
    
    推荐文章