首页 > 解决方案 > Apollo GraphQL 缓存问题(cacheRedirects 和 readFragment)

问题描述

我是 Apollo 和 Apollo 缓存的新手。我一直在写一个演示项目,遇到了两个问题:

  1. 无法cacheRedirects正常工作:

在我的演示中,我“加载所有”COVID19 测试数据,它查询 API 并返回包括加拿大在内的 3 个国家/地区的结果数组。然后我尝试加载单个结果(“加载加拿大”)以使其使用我的cacheRedirects解析器。我想我已经正确设置了这个,但它总是回到 API 来进行查询,而不是从缓存中读取。

这是我的带缓存的 Apollo 客户端:

const client = new ApolloClient({
  uri: "https://covid19-graphql.now.sh",
  cache: new InMemoryCache({
    dataIdFromObject: obj => {
      console.log("in cache: obj:", obj);
      let dataId = null;
      switch (obj.__typename) {
        case "Country":
          dataId = obj.__typename + "_" + obj.name;
          break;
        default:
          dataId = defaultDataIdFromObject(obj);
      }
      console.log("in cache: dataId:", dataId);
      return dataId;
    },
    cacheRedirects: {
      Query: {
        country: (_, args, { getCacheKey }) => {
          console.log("in cacheRedirects:", _, args);
          const cacheKey = getCacheKey({ __typename: "Country", ...args });
          console.log("cacheKey:", cacheKey);
          return cacheKey;
        }
      }
    }
  })
  // connectToDevTools: true
});
  1. 我不知道如何执行readFragment

我在这段代码中尝试了很多不同的配置,但我从来没有得到任何结果。

这是我的功能:

const ReadFragment = () => {
  console.log("in ReadFragment");
  try {
    const data = client.readFragment({
      id: GET_DATA.countryData,
      fragment: gql`
        fragment mostRecent on country {
          id
          text
          complete
        }
      `
    });
    if (data) {
      console.log(data);
      return (
        <div>
          From Fragment: {JSON.stringify(data)}
        </div>
      );
    } else {
      return <div>From Fragment: not found</div>;
    }
  } catch (error) {
    // console.error(error);
    return <div>From Fragment: not found</div>;
  }
};

额外问题:我似乎无法让 Apollo Client Developer Tools 扩展在 Chrome 浏览器中工作。这仍然有效吗?我的代码似乎从未连接到它。(取消注释掉connectToDevTools: true。)似乎能够检查缓存的内容对于开发和学习非常有用。是否有另一种查看缓存内容的方法?

标签: reactjsreact-apolloapollo-cache-inmemoryapollo-boost

解决方案


Apollo GraphQL 自己维护缓存,当然你不必 -

export declare type FetchPolicy = 'cache-first' | 'network-only' | 'cache-only' | 'no-cache' | 'standby';

如果您查看 fetchPolicy 声明,那么有几个选项可以做到这一点 -

  1. 仅限网络

    const { data } = useQuery(GET_LIST, {
    fetchPolicy: 'network-only'
    });
    
  2. 缓存优先

    const { data } = useQuery(GET_LIST, {
    fetchPolicy: 'cache-first'
    });
    
  3. 仅缓存

    const { data } = useQuery(GET_LIST, {
    fetchPolicy: 'cache-only'
    });
    

同样,其余选项也可以根据需要查看。

如果您想保持状态并做一些工作,那么为这些查询编写解析器 -

const client = new ApolloClient({
  uri: apollo.networkInterface,
  cache,
  resolvers: {
    Mutation: {
        searchQuery: (launch, _args, { cache }) => {
            console.log(cache); // cache can be queried here
            // read from cache if planning to modify the data
            //const { searchQuery } = cache.readQuery({ query: GET_LIST });
            cache.writeQuery({
                query: GET_LIST,
                data: {searchQuery:_args.searchQuery}
              });
          },
      },
  },
})

Chrome 客户端确实可以工作,但必须与 graphql 服务器建立连接。否则它不会显示在 chrome 中。


推荐阅读