【问题标题】:Why does graphql not inject my data into react component prop?为什么 graphql 不将我的数据注入到反应组件道具中?
【发布时间】:2020-02-11 10:11:53
【问题描述】:

我正在使用这个tutorial 创建一个将使用 Markdown 页面的 gatsby 博客。

我正在尝试创建一个“post-repeater”组件,它将遍历我的所有帖子并使用看起来像这样的 frontmatter 创建指向它们的链接。

---
path: "/blog/my-first-post"
date: "2019-05-04"
title: "My first blog post"
---

我有一个正确提取数据的 graphQl 查询。

我的组件看起来像这样。

import React from "react"

import "../styles/post-repeater.scss"
import { graphql, Link } from "gatsby"

export default function PostRepeater({postQuery}){
    console.log('my data:',postQuery);
    return(

        <>
            {postQuery.map(instance => 
                <div className="post">
                    <h2>{instance.title}</h2>
                    <span className="datePosted">{instance.date}</span>
                    <span className="readTime"></span>
                    <p></p>
                    <Link to={instance.path}>Read More</Link>
                    <hr />
                </div>
            )}
        </>

    )
}

export const postQuery = graphql`
query MyQuery {
    allMarkdownRemark {
      edges {
        node {
          frontmatter {
            path
            title
            date
          }
        }
      }
    }
  }
`

如果我从 PostRepeater 组件中放置一个 postQuery 的 console.log,它会以未定义的形式返回。因此,即使我遵循上面教程中的相同布局,组件似乎也永远不会获取数据。

如果我从组件外部放置console.log('data', postQuery);,我会在控制台中得到以下信息。

数据 2575425095

我做错了什么?

【问题讨论】:

标签: javascript reactjs graphql gatsby


【解决方案1】:

在进行查询后gatsby 将其作为匹配查询的对象注入。

在您的情况下,正如您在 GraphiQL 中看到的那样,您将获得一个带有初始键 data 的对象。

{
  "data": {
    "allMarkdownRemark": {
      "edges": [
        {
          "node": {
            "frontmatter": {
              "title": "...",
              "date": ...
            }
          }
        }
      ]
    }
  }
}

您尝试做的是destructing 不存在的密钥postQuery

此外,您仍然可以在组件范围之外将其记录为从export const postQuery 导出的值

export const postQuery = graphql`
  query MyQuery {
    allMarkdownRemark {
      edges {
        node {
          frontmatter {
            path
            title
            date
          }
        }
      }
    }
  }
`;

//       v  Logs the query id
console.log('my data:', postQuery);

//                                               v Is not defined
export default function PostRepeater({ data, postQuery }) {

  //                       v Shadowing the outter value of postQuery
  console.log('my data:', postQuery);

  // The query injected as "data" object
  console.log('my data:', data);

  return (
    <>
      //      v Be aware of which object you query, edges is an array
      {data.allMarkdownRemark.edges.map(...)}
    </>
  );
}

【讨论】:

  • 我不知道为什么,但我在 PostRepeater 组件内的两个日志都返回为未定义,而组件外的日志确实显示了您上面写的 ID。
  • 答案里解释了,你没看懂哪一部分?
  • 另外也要看你的结构,页面查询和静态查询是有区别的,请务必按照文档进行
  • 也许我只需要阅读更多文档。但是我确实将您的答案复制并粘贴到了我的组件中,但它不起作用。 PostRepeater 组件内的两个控制台日志返回未定义。
【解决方案2】:

自动附加到 props 的 graphql 查询的导出仅适用于页面组件。对于任何非页面组件,您需要使用 StaticQuery 组件或 useStaticQuery 挂钩。

在这里阅读更多: https://www.gatsbyjs.com/docs/static-query/

下面是使用 useStaticQuery 挂钩的代码的样子

import React from "react"

import "../styles/post-repeater.scss"
import { graphql, useStaticQuery, Link } from "gatsby"

export default function PostRepeater() {
  const data = useStaticQuery(graphql`
    query MyQuery {
      allMarkdownRemark {
        edges {
          node {
            frontmatter {
              path
              title
              date
            }
          }
        }
      }
    }
    `)
   // you might have multiple nodes in which case you must use filter 
   // or find to get node which contains your data. 
   const postQuery = data.allMarkdownRemark.edges[0].node.frontmatter;

   return (
     <>
       {postQuery.map(instance => 
         <div className="post">
           <h2>{instance.title}</h2>
           <span className="datePosted">{instance.date}</span>
           <span className="readTime"></span>
           <p></p>
           <Link to={instance.path}>Read More</Link>
           <hr />
         </div>
       )}
     </>
   )

}

【讨论】:

    猜你喜欢
    • 2017-09-03
    • 2019-02-08
    • 2020-04-22
    • 2016-05-15
    • 2021-10-15
    • 2016-11-20
    • 2020-10-14
    • 2020-08-03
    • 1970-01-01
    相关资源
    最近更新 更多