Graphql 查询结果在 UI 中正确返回,但数据在应用程序内显示为“未定义”

Posted

技术标签:

【中文标题】Graphql 查询结果在 UI 中正确返回,但数据在应用程序内显示为“未定义”【英文标题】:Graphql query result returning correctly in the UI, but data showing as "undefined" inside app 【发布时间】:2021-05-09 01:08:59 【问题描述】:

我正在从事一个 Gatsby 项目,我在 Graphql 中从 JSON 数据中查询,该数据在 Graph IU 中正确返回所有数据,我什至可以将其注销并在浏览器 devtools 中查看结果。但是由于某种原因,当我缩短我的 Graphql 字段以使用短名称时,只有部分数据正在通过,正如您将在下面的代码中看到的那样:

这里是静态查询组件:

import  useStaticQuery, graphql  from "gatsby"

export const UseFooterDataQuery = () => 
  const allFooterData = useStaticQuery(graphql`
    query FooterDataQuery 
      allDataJson 
        edges 
          node 
            id
            title
            url 
              id
              linkName
              linkUrl
            
          
        
      
    
  `)
  return allFooterData

这是 Graphql IU 中相同查询的结果:


  "data": 
    "allDataJson": 
      "edges": [
        
          "node": 
            "id": "8e2be307-9298-52b2-9a78-cf1a9dfa5b35",
            "title": "Features",
            "url": [
              
                "id": "022",
                "linkName": "Version Control",
                "linkUrl": "version-control"
              ,
              
                "id": "023",
                "linkName": "Design Collaboration",
                "linkUrl": "design-collaboration"
              ,
              
                "id": "024",
                "linkName": "Developer Handoff",
                "linkUrl": "developer-handoff"
              
            ]
          
        
      ]
    
  ,
  "extensions": 

这是我的功能组件。看到我正在控制台记录 UseFooterDataQuery() 函数和返回 allFooterList 我只是缩短了 Graphql 字段名称:

import React from "react"
import  Link  from "gatsby"
import  UseFooterDataQuery  from "../hooks/UseFooterDataQuery"

export default function Footer() 
  const getAllFooterList = () => 
    const allFooterList = []
    const allFooter = UseFooterDataQuery()
    allFooter.allDataJson.edges.forEach(footerEdge => 
      allFooterList.push(
        id: footerEdge.node.id,
        title: footerEdge.node.title,
        linkName: footerEdge.node.url.linkName,
        linkUrl: footerEdge.node.url.linkUrl,
        linkId: footerEdge.node.url.id,
      )
    )
    return allFooterList
  

  const allFooterList = getAllFooterList()

  console.log(UseFooterDataQuery())
  console.log(allFooterList)

  return (
    <FooterSection>
      <FooterContainer>
        allFooterList.map(data => 
          return (
            <div key=data.id>
              <h3>data.title</h3>
              <ul>
                <li>
                  <Link to=`/$data.linkUrl`>data.linkName</Link>
                </li>
              </ul>
            </div>
          )
        )
      </FooterContainer>
      <div>
        © new Date().getFullYear(), Built with
        ` `
        <a href="https://www.gatsbyjs.com">Gatsby</a>
      </div>
    </FooterSection>
  )


这里返回上面的控制台日志。如您所见,UseFooterDataQuery() 函数返回了所有数据,但我无法弄清楚 allFooterList 的返回发生了什么,其中我的数据 linkId、linkName 和 linkUrl 未定义。

…​
allDataJson: …​​
edges: (1) […]​​​
0: …​​​​
node: …​​​​​
id: "8e2be307-9298-52b2-9a78-cf1a9dfa5b35"​​​​​
title: "Features"​​​​​
url: (3) […]​​​​​​
0: Object  id: "022", linkName: "Version Control", linkUrl: "version-control" ​​​​​​
1: Object  id: "023", linkName: "Design Collaboration", linkUrl: "design-collaboration" ​​​​​​
2: Object  id: "024", linkName: "Developer Handoff", linkUrl: "developer-handoff" ​​​​​​
length: 3​​​​​​
<prototype>: Array []​​​​​
<prototype>: Object  … ​​​​
<prototype>: Object  … ​​​
length: 1​​​
<prototype>: Array []​​
<prototype>: Object  … ​
<prototype>: …

allFooterList console.log 返回:

0: …​​
id: "8e2be307-9298-52b2-9a78-cf1a9dfa5b35"​​
linkId: undefined​​
linkName: undefined​​
linkUrl: undefined​​
title: "Features"​​
<prototype>: Object  … ​
length: 1​
<prototype>: [

【问题讨论】:

【参考方案1】:

不需要在 state 或其他 vars 中复制数据 ...您可以简单地将其“别名”以缩短代码,例如const items = allFooter.allDataJson.edges;items.map(...

 items.map( element =>  element.node.id  // array element
 items.map( node =>  node.id   // destructured 'node' prop from array element
 items.map( node:footerItem =>  footerItem.id   // aliased/renamed destructured array element

在外部文件中定义 'hook' UseFooterDataQuery [几乎] 没用......没有自定义逻辑,没有理由...... 仅在单独的 ('footer.graphql') 文件中定义 graphql 查询 (搜索导入gql文件)

您应该在map 内部使用map,对于节点idtitle 使用外部,对于url 使用内部:

.

const allFooterData = useStaticQuery( FOOTER_QUERY );
const items = allFooter.allDataJson.edges;

...
   items.map( node => 
      return (
        <div key=node.id>
          <h3>node.title</h3>
            node.url.map( (data) => 
              return (
                <ul key=data.id>
                  <li>
                    <Link to=`/$data.linkUrl`>data.linkName</Link>
                  </li>
                </ul>

【讨论】:

【参考方案2】:

@xadm,这行得通!非常感谢! 以下是调整后的样子:

import React from "react"
import  Link  from "gatsby"
import  UseFooterDataQuery  from "../hooks/UseFooterDataQuery"

export default function Footer() 
  const allFooterList = UseFooterDataQuery().allDataJson.edges

  // console.log(allFooterList, `==============> FOOTERLIST`)

  return (
    <div>
      <div>
        allFooterList.map(( node ) => 
          console.log(node, `==============> NODE`)
          return (
            <div key=node.id>
              <h3>node.title</h3>
              node.url.map(data => 
                console.log(data, `====================> DATA`)
                return (
                  <ul key=data.id>
                    <li>
                      <Link to=`/$data.linkUrl`>data.linkName</Link>
                    </li>
                  </ul>
                )
              )
            </div>
          )
        )
      </div>
    </div>
  )

这是控制台日志:

…​                        ==============> NODE
id: "8e2be307-9298-52b2-9a78-cf1a9dfa5b35"​
title: "Features"​
url: Array(3) [ …, …, … ]​
<prototype>: Object  … 
---------------------------------------------------
…                     ====================> DATA
id: "022"​
linkName: "Version Control"​
linkUrl: "version-control"​
<prototype>: Object  … 
---------------------------------------------------
…​                        ====================> DATA
id: "023"​
linkName: "Design Collaboration"​
linkUrl: "design-collaboration"​
<prototype>: Object  … 
---------------------------------------------------
…​                        ====================> DATA
id: "024"​
linkName: "Developer Handoff"​
linkUrl: "developer-handoff"​
<prototype>: Object  …  
---------------------------------------------------

【讨论】:

以上是关于Graphql 查询结果在 UI 中正确返回,但数据在应用程序内显示为“未定义”的主要内容,如果未能解决你的问题,请参考以下文章

为啥 GraphQL 查询返回 null?

为啥 GraphQL 查询返回 null?

为啥 GraphQL 查询返回 null?

graphql 查询或突变能否返回标量值

对 GraphQL 中嵌套类型的深度查询返回 NULL

如何从 MySQL 查询中将 json 返回到 GraphQL?