首页 > 解决方案 > 为什么 graphql 不将我的数据注入到反应组件道具中?

问题描述

我正在使用本教程创建一个将使用 Markdown 页面的 gatsby 博客。

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

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

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

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

我究竟做错了什么?

标签: javascriptreactjsgraphqlgatsby

解决方案


After making a query gatsby injects it as an object matching the query.

In your case, as you see in GraphiQL you get an object with the initial key data.

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

What you tried to do, is destructing a not existing key postQuery.

Moreover, you still can log it outside of the component scope as the value exported from 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(...)}
    </>
  );
}

推荐阅读