5

有几个类似的问题,但除了 pages 文件夹中的组件之外,没有一个问题能帮助我真正理解在(类)组件中使用 GraphQL。

我的项目结构如下所示:

-src
--components
---aboutBody
----index.js
--pages
---about.js

我有一个名为about(Prismic 单页类型)的页面组件,并设置了一些组件来“填充”此页面(已清理以提高可读性)。

class AboutPage extends Component {

  render() {
    return (
        <LayoutDefault>
          <AboutBody
            introHeadline={this.props.data.prismicAbout.data.intro_headline.text}
            introParagraph={this.props.data.prismicAbout.data.intro_paragraph.text}
          />
        </LayoutDefault>
    )
  }

}

export default AboutPage

这就是我的查询的样子(在两个文件中都这样):

export const aboutQuery = graphql`
  query About {
    prismicAbout {
      data {

        # Intro Block
        intro_headline {
          text
        }
        intro_paragraph {
          text
        }
      }
    }
  }
`

(如果我在底部缺少一个括号,这是由于清理了 SO 的查询示例——如前所述,它在我的页面组件中工作)。

我的 graphql 查询位于AboutPage页面组件的底部。它就像一个魅力和预期的那样工作。

但是为了稍微清理一下这个页面,我想创建适当的组件并将我的查询放在每个组件中(例如aboutBodyaboutCarousel),再次清理一下:

class AboutBody extends Component {

  render() {

    return (
      <StyledIntro>
        <h3>About</h3>
        <h1>{this.props.data.prismicAbout.data.intro_headline.text}</h1>
      </StyledIntro>
    )
  }

}

export default AboutBody

我从我的about页面组件中删除了查询并将其放入我的AboutBody组件中(完全如上所示的方式)。

但是这样它总是返回错误Cannot read property 'prismicAbout' of undefined(我什至不能控制台记录数据,它总是返回相同的错误)。

import { graphql } from "gatsby"在两个文件中都使用了。

长话短说,我怎样才能实现在我的类组件中放置一个查询并只呈现该组件而不澄清我的页面组件中的道具,如下所示:

class AboutPage extends Component {

  render() {
    return (
        <LayoutDefault>
          <AboutBody />
        </LayoutDefault>
    )
  }

}

一些博客文章提到了 GraphQL 查询片段,但不确定这是否是正确的用例,或者这只是一个愚蠢的初学者错误......

4

3 回答 3

8

那是因为你不能在你的组件中使用这样的 graphql。

要在组件中使用 graphql,您有两个选项:useStaticQuery函数或StaticQuery组件,都来自 graphql

对于useStaticQuery

import React from "react"
import { useStaticQuery, graphql } from "gatsby"

const MyElement = () => {
  const data = useStaticQuery(graphql`
     query About {
       prismicAbout {
         data {
           intro_headline {
             text
           }
           intro_paragraph {
             text
           }
         }
       }
     }
   `)

   return (
      <StyledIntro>
        <h3>About</h3>
        <h1>{this.props.data.prismicAbout.data.intro_headline.text}</h1>
      </StyledIntro>
   )
}

export default MyElement

staticQuery

import React from 'react'
import { StaticQuery, graphql } from 'gatsby';

const MyElement = () => {
   return(
      <StaticQuery
            query About {
              prismicAbout {
                data {
                   intro_headline {
                       text
                       }
                       intro_paragraph {
                          text
                       }
                   }
                }
             }
         `}
         render={data => (
            <StyledIntro>
               <h3>About</h3>
               <h1>{this.props.data.prismicAbout.data.intro_headline.text}</h1>
            </StyledIntro>
         )}
      />
   )
}

export default MyElement

希望对你有帮助!

于 2019-08-23T07:19:50.347 回答
4

您只能在页面组件中使用类似的查询。一种选择是仅在页面中查询它,然后将数据作为道具传递给您的组件。另一种是在组件中使用静态查询。

如果您的查询中有变量,那么您不能使用静态查询。在这种情况下,您应该在页面中全部查询,然后将其传入,或者您可以将与该组件相关的查询部分放在该组件文件中的片段中,然后在页面查询中使用该片段。

在组件中使用片段然后将数据传递到组件中的示例:

// MyComponent.js
import React from "react"
import { graphql } from 'gatsby'

const MyComponent = (props) => {

  const { myProp: { someData } }  = props

  return (
    <div>
        my awesome component
    </div>
  )
}

export default MyComponent

export const query = graphql`
  fragment MyAwesomeFragment on Site {
     someData {
         item
     }
  }
`
// MyPage.js
import React from "react"
import { graphql } from "gatsby"

import MyComponent from "../components/MyComponent"

export default ({ data }) => {
  return (
    <div>
      {/*
        You can pass all the data from the fragment
        back to the component that defined it
      */}
      <MyComponent myProp={data.site.someData} />
    </div>
  )
}
export const query = graphql`
  query {
    site {
      ...MyAwesomeFragment
    }
  }
`

在Gatsby 文档中阅读有关使用片段的更多信息。

于 2019-08-24T01:37:23.297 回答
0

如果您需要在基于类的组件中呈现查询。这对我有用:

import React, { Component } from 'react';
import { StaticQuery, graphql } from 'gatsby';

class Layout extends Component {
  render() {
    return (
      <StaticQuery
        query={graphql`
          query SiteTitleQuery {
            site {
              siteMetadata {
                title
              }
            }
          }
        `}
        render={data => {
          return (
            <main>
              {!data && <p>Loading...</p>}
              {data && data.site.siteMetadata.title}
            </main>
          )
        }}
      />
    );
  }
}
于 2021-06-21T09:35:24.187 回答