Apollo Cache - 为查询字段名称返回的未定义类型的对象缺少选择集

Ruf*_*eng 1 reactjs graphql react-apollo apollo-client

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

我想将数据片段存储到 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
Run Code Online (Sandbox Code Playgroud)

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

我的组件.tsx

const result = client.readQuery({ query: gql`
      query namesCached {
        names @client
      }`
    })
console.log(result)
Run Code Online (Sandbox Code Playgroud)

这总是陷入这个错误:

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

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

我也在使用打字稿

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

编辑 所以这里是我真实的例子,使它更接近我的真正问题:

<Query
    query={fetchdata}
    onCompleted={({ repository }) => client.writeData({
        data: {
          issues: repository.issues.edges
        }
      })
    }
  >
Run Code Online (Sandbox Code Playgroud)

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

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

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

Dan*_*den 5

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

names: [
  {
    __typename: 'Name',
    id: 0,
    firstName: 'Mario',
  },
  {
    __typename: 'Name',
    id: 1,
    firstName: 'Luigi'
  }
]
Run Code Online (Sandbox Code Playgroud)

然后像这样查询状态:

query namesCached {
  names @client {
    firstName
  }
}
Run Code Online (Sandbox Code Playgroud)

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

names: [
  'Mario',
  'Luigi',
]
Run Code Online (Sandbox Code Playgroud)

那么你不需要选择集:

query namesCached {
  names @client
}
Run Code Online (Sandbox Code Playgroud)