首页 > 解决方案 > GraphQL 内联片段检查是否存在,然后在 .map 中输出

问题描述

我在 gatsbyJS 中有一个通过 graphQL 查询进行映射的反应组件,到目前为止它可以工作,但是我已经在 graphQL 查询中引入了一个内联片段,其中两个实际上我想检查片段是否存在然后输出代码,否则我的所有地图输出真实内容后输出空div。为简洁起见,我没有包括整个查询或所有代码。

希望有人能帮忙,谢谢!

这是我的地图和 jsx

{data.datoCmsProject.projectBlock.map(projectEntry => { 

        return (  

          <>

          // I want to check here if    DatoCmsProjectBlockGrid fragment exists then render below       

          <BlockGridWrapper>
            <BlockGrid key={projectEntry.id}>

                <div>{projectEntry.titleOfGridSection}</div>
            </BlockGrid>
          </BlockGridWrapper>

        // end check for DatoCmsProjectBlockGrid

        // I want to check here if DatoCmsSingleProjectBlockContent fragment exists, then render below

         <NewBlock key={projectEntry.id}> 

          <img key={imageEntry.originalId} src={imageEntry.url}/>

         </NewBlock>

        //end check for DatoCmsSingleProjectBlockContent

...

这是我的查询

projectBlock{
        ... on DatoCmsSingleProjectBlockContent {
            id
            titleOfSection
            descriptionOfImage
            descriptionToggle
            wideView
            imageTextSide
            imageAssetHideShow
            imageAsset{
              url
              originalId
            }
          }
        ... on DatoCmsProjectBlockGrid {
          id
          titleOfGridSection
        }
      }   

标签: reactjsgraphqlgatsby

解决方案


您可以利用该__typename字段来确定返回对象的类型,然后渲染适当的组件。

projectBlock {
  __typename
  ... on DatoCmsSingleProjectBlockContent {
    id
    # other fields
  }
  ... on DatoCmsProjectBlockGrid {
    id
    # other fields
  }
}   

在这种情况下,__typename将解析为DatoCmsSingleProjectBlockContent,或该字段DatoCmsProjectBlockGrid的任何其他可能类型。projectBlock如果您不想渲染其他可能的类型,则应先过滤数组或使用reduce而不是达到map相同的效果:

data.datoCmsProject.projectBlock
  .filter(({ __typename }) => __typename === 'DatoCmsSingleProjectBlockContent' || __typename === 'DatoCmsProjectBlockGrid')
  .map(projectEntry => {
  if (projectEntry.__typename === 'DatoCmsSingleProjectBlockContent') {
    return <BlockGridWrapper/>
  }
  return <NewBlock/>
})

推荐阅读