【问题标题】:Apollo Cache - Missing selection set for object of type undefined returned for query field namesApollo Cache - 为查询字段名称返回未定义类型的对象缺少选择集
【发布时间】:2019-07-26 04:24:36
【问题描述】:

我正在使用 apollo-boost 构建一个应用程序,其中应该已经包含一些用于使用 graphql 进行反应应用程序的包。

当我想将数据片段存储到我的 Apollo 缓存中时,我遇到了一个错误。

ApolloClient.tsx

import ApolloClient from 'apollo-boost'
import { InMemoryCache } from 'apollo-cache-inmemory'

import { secretToken } from './secretToken'

const cache = new InMemoryCache({
})

const client = new ApolloClient({
  uri: 'https://someUrlIremovedForTheQuestion.com',
  request: async operation => {
    operation.setContext({
      headers: {
        Authorization: secretToken
      }
    })
  },
  cache
})

client.writeData({
  data: {
    names: [
      {
        firstName: 'Mario'
      },
      {
        firstName: 'Luigi'
      }
    ]
  }
})
export default client

现在我正在尝试访问我在同一个 apollo 配置中创建的这些名称:

MyComponent.tsx

const result = client.readQuery({ query: gql`
      query namesCached {
        names @client
      }`
    })
console.log(result)

这总是陷入这个错误:

Missing selection set for object of type undefined returned for query field names

如果我正在处理单个数据,例如 name: 'Mario',它可以完美地检索该数据,但对于更深层次的对象或数组,它总是会因此错误而失败。

我也在使用 Typescript

知道可能是什么吗?堆栈溢出向我展示了几个无效的答案,而 GitHub 也没有为我提供解决方案......

编辑 因此,这是我的真实示例,以使其更接近我的实际问题:

<Query
    query={fetchdata}
    onCompleted={({ repository }) => client.writeData({
        data: {
          issues: repository.issues.edges
        }
      })
    }
  >

基本上我正在做一个查询,一旦完成我想将它存储在缓存中,因为我多次检查它以比较和过滤一些结果。

我尝试了repository,但仍然出现同样的错误

要检索数据,我正在执行与上述相同的操作,但使用 issues 而不是 names

【问题讨论】:

    标签: reactjs graphql react-apollo apollo-client


    【解决方案1】:

    文档可以更好地强调这一点,但您存储在缓存中的对象应该始终具有适当的__typename。此外,如果您要在缓存中存储多个相同类型的对象,则应包含id 属性以确保为每个项目生成唯一的缓存键。换句话说,你的初始状态应该是:

    names: [
      {
        __typename: 'Name',
        id: 0,
        firstName: 'Mario',
      },
      {
        __typename: 'Name',
        id: 1,
        firstName: 'Luigi'
      }
    ]
    

    然后你像这样查询状态:

    query namesCached {
      names @client {
        firstName
      }
    }
    

    值得一提的是,除非您要存储对象,否则上述内容不是必需的。如果您正在使用标量,如下所示:

    names: [
      'Mario',
      'Luigi',
    ]
    

    那么你就不需要选择集了:

    query namesCached {
      names @client
    }
    

    【讨论】:

    • 嗨丹尼尔,正是我一直在阅读你在这类主题中所做的一些答案,所以我很高兴你能抽出时间来帮助我。这个答案真的解释了很多,谢谢。让我更新我的问题,从应用程序中添加我的真实对象(因为马里奥和路易吉是一种模拟数据)
    • 当您查询issues 时,您是否包含选择集(即该字段的子字段)?如果您可以共享您的存储库,那么只查看所有代码会更容易。
    • 先生!我所有的尊重:)。我的查询对每个子查询都有 __typename(因为它来自 graphql 本身),但缺少指定我想在那里检索的对象(id、或 firstName 或 age 等)。我一直在检查文档中的解释,但没有找到。您介意将文档发送给我,其中解释了 __typename 的重要性以及为什么缓存需要唯一键,例如 id?再次:谢谢:)
    猜你喜欢
    • 2021-07-27
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多