How to access data from query inside component?

Viewed 144

I need to access { excerpt, title, author, category, slug, readTime, image } those data from the query, I have tried many time, but I can't think how to do.

my code is:

import React from 'react'
import PropTypes from 'prop-types'
import { Helmet } from 'react-helmet'
import { useStaticQuery, graphql } from 'gatsby'

const SEO = () => {
  return <div>SEO Component</div>
}

export const query = graphql`
  {
    allMdx(limit: 3, sort: { fields: frontmatter___date, order: DESC }) {
      nodes {
        excerpt
        frontmatter {
          title
          author
          category
          date(formatString: "MMMM, Do YYYY")
          slug
          readTime
          image {
            childImageSharp {
              gatsbyImageData
            }
          }
        }
        id
      }
    }
  }
`

export default SEO

after that I want like this

const SEO = ({ excerpt, title, author, category, slug, readTime, image }) => {
  return <div>SEO Component</div>
}

Then I will access those data inside my SEO component.

I'm new in graphQL

Thank you.

1 Answers

Queried data is inside props.data, destructured as { data }. Page queries, the one you are showing in your SEO component are only available in the top-level components (pages).

The idea when dealing with this kind of component is to move the query for each page you want and drill down the data to the SEO component through props. For example:

import * as React from 'react'
import { graphql } from 'gatsby'

 const HomePage = ({data}) => {
  console.log("your queried data is", data);

  return (
    <div>
      This is your home page
    </div>
  )
}

export const query = graphql`
  {
    allMdx(limit: 3, sort: { fields: frontmatter___date, order: DESC }) {
      nodes {
        excerpt
        frontmatter {
          title
          author
          category
          date(formatString: "MMMM, Do YYYY")
          slug
          readTime
          image {
            childImageSharp {
              gatsbyImageData
            }
          }
        }
        id
      }
    }
  }
`

export default HomePage

In the example above, allMdx data is inside props.data.allMdx. At this point, you can do something like:

 const HomePage = ({data}) => {
  console.log("your queried data is", data);

  return (
    <div>
    <SEO {...data.allMdx.nodes[0].frontmatter} excerpt={data.allMdx.nodes[0].excerpt}/>
    </div>
  )
}

Note that the spread operator (...) will allow you to pass the list of props under frontmatter object, there you only need to get them by destructuring props in the SEO component like:

const SEO = ({ excerpt, title, author, category, slug, readTime, image }) => {}

Since the excerpt is in another level than the rest of the frontmatter, you can pass it isolated as another props or you may want to create a new object mixing all properties of the current allMdx data and pass the whole object using the spread operator but the approach of the snippet above will work for your use-case. Tweak it as you wish.

Related