【问题标题】:Apollo Client cacheApollo 客户端缓存
【发布时间】:2017-03-18 13:53:34
【问题描述】:

我刚开始在 React 应用程序上使用 apollo 客户端,但我被困在缓存上。 我有一个包含产品列表的主页,我在其中进行查询以获取这些产品的 ID 和名称,并在产品页面中查询 ID、名称、描述和图像。

我希望如果用户首先访问主页,然后访问特定的产品页面,只查询该产品的描述和图像,同时在加载过程中显示名称(因为我应该已经缓存了它)。 我遵循了文档中的“控制商店”部分 (http://dev.apollodata.com/react/cache-updates.html),但仍然无法解决。

当我们转到产品页面时完成的查询仍然要求产品的 id 和名称,而它们应该被缓存,因为我已经要求它们了。

我想我错过了一些东西,但我无法弄清楚。 以下是部分代码:

// Create the apollo graphql client.
const apolloClient = new ApolloClient({
    networkInterface: createNetworkInterface({
        uri: `${process.env.GRAPHQL_ENDPOINT}`
    }),
    queryTransformer: addTypename,
    dataIdFromObject: (result) => {
        if (result.id && result.__typename) {

            console.log(result.id, result.__typename); //can see this on console, seems okey
            return result.__typename + result.id;
        }

        // Make sure to return null if this object doesn't have an ID
        return null;
    },
});

// home page query
// return an array of objects (Product)
export default  graphql(gql`
   query ProductsQuery {
        products {
            id, name
        }
    }
`)(Home);

//product page query
//return an object (Product)
export default graphql(gql`
   query ProductQuery($productId: ID!) {
        product(id: $productId) {
            id, name, description, image
        }
    }
`,{
    options: props => ({ variables: { productId:  props.params.id } }),
    props: ({ data: { loading, product } }) => ({
        loading,
        product,})
})(Product);

还有我的控制台输出:

【问题讨论】:

    标签: reactjs graphql apollo


    【解决方案1】:

    这个问题很老了,但是,有一个解决方案可以使用cacheRedirects将查询映射到正确的位置

    在我的项目中,我有一个projects 查询和一个project 查询。

    我可以创建一个cacheRedirect,如下所示:

    const client = new ApolloClient({
      uri: "http://localhost:3000/graphql",
      request: async (operation) => {
        const token = await localStorage.getItem('authToken');
        operation.setContext({
          headers: {
            authorization: token
          }
        });
      },
      cacheRedirects: {
        Query: {
          project: (_, { id }, { getCacheKey }) => getCacheKey({ id, __typename: 'Project' })
        }
      }
    });
    

    然后,当我加载仪表板时,有 1 个查询得到 projects。然后在导航到单个 project 时。没有网络请求,因为它正在从缓存中读取?

    阅读full documentation on Cache Redirects

    【讨论】:

      【解决方案2】:

      你的问题的答案实际上有两个部分:

      1. 客户端实际上无法确定这些查询解析到缓存中的同一个对象,因为它们具有不同的路径。一个以products 开头,另一个以product 开头。客户端解析器有一个open PR,即使您没有明确查询它们,它也可以让您向客户端提示在缓存中的何处查找内容。我希望我们会在一两周内发布该功能。

      2. 1234563相反,所有查询现在都是完全静态的。这意味着即使您的查询部分在缓存中,完整的查询也会发送到服务器。这有许多优点,在此blog post 中列出。

      通过在选项中设置returnPartialData: true,您仍然可以首先显示缓存中的部分。

      【讨论】:

      猜你喜欢
      • 2021-04-21
      • 2020-11-03
      • 2021-03-11
      • 2020-08-07
      • 2021-07-30
      • 2019-04-02
      • 2021-06-05
      • 2018-01-25
      相关资源
      最近更新 更多