首页 > 解决方案 > 为什么在 api 工作正常时在片段上使用 apollo 客户端查询给我一个空对象?

问题描述

我想获取有关动态类型的数据。为此,我在 graphql 查询中使用片段。Api 在 graphql 操场上运行良好,但是当我尝试将它与 react-apollo 客户端集成时,它给了我一个空对象以及警告!在控制台中进行启发式片段匹配。

当我使用 npm install 和 npm run start 时它也可以工作,但是当我切换到 yarn install 和 yarn run start 时它给了我一个错误。

我使用了 IntrospectionFragmentMatcher 并将 fetchPolicy 设置为“缓存和策略”。

我还为客户端配置共享了 IntrospectionFragmentMatcher 的代码。

query GetContentSections($contentPageId: Int) {
  contentSection {
    searchContentSections(contentPageId: $contentPageId, status: [ACTIVE]) {
      id
      contentLayoutId
      sort
      sectionContainers {
        id
        sort
        snippets {
          id
          sort
          type: __typename
          ...quote
          ...text
          ...image
          ...video
          ...audio
          ...button
          ...popup
          ...map
          ...code
          ...app
        }
      }
    }
  }
}
fragment text on ContentSnippetTextType{
  text
}
fragment image on ContentSnippetImageType{
  assetId
}
fragment video on ContentSnippetVideoType{
  assetId
}
fragment audio on ContentSnippetAudioType{
  assetId
}
fragment button on ContentSnippetButtonType{
  hyperlink
  innerText
  foregroundColor
  fontColor
  backgroundColor
}
fragment popup on ContentSnippetPopupType{
  text
  link
}
fragment quote on ContentSnippetQuoteType {
  text
  author
}
fragment map on ContentSnippetMapType {
  longitude
  latitude
  zoom
}
fragment code on ContentSnippetCodeType {
  cssFileLocation
  htmlFileLocation
  javascriptFileLocation
}
fragment app on ContentSnippetAppType {
  appId
}

const fm = new IntrospectionFragmentMatcher({
  introspectionQueryResultData:{
    "__schema": {
      "types": [
        {
          "kind": "INTERFACE",
          "name": "ContentSnippetInterface",
          "possibleTypes": [
            { "name": "ContentSnippetAppType" },
            { "name": "ContentSnippetAudioType" },
            { "name": "ContentSnippetButtonType" },
            { "name": "ContentSnippetCodeType" },
            { "name": "ContentSnippetImageType" },
            { "name": "ContentSnippetMapType" },
            { "name": "ContentSnippetPopupType" },
            { "name": "ContentSnippetQuestionType" },
            { "name": "ContentSnippetQuoteType" },
            { "name": "ContentSnippetTextType" },
            { "name": "ContentSnippetVideoType" },
            { "name": "ContentSnippetSpacerType" }
          ]
        },
      ]
    }
  }
});

export default new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache({ fm }),
});

我希望所有字段都取决于类型。它可以是动态的,因此仅在运行时决定。但它给了我一个空的对象。

标签: javascriptreactjsgraphqlreact-apolloapollo-client

解决方案


InMemoryCache 接受一个配置对象作为它的参数。该对象的属性应与docs 中显示的内容相匹配。您可以通过设置fragmentMatcher属性传入 FragmentMatcher。但是,在您的代码中,您设置了一个名为的属性fm。你应该这样做:

new InMemoryCache({ fragmentMatcher: fm })

推荐阅读