【问题标题】:GraphQL query works in Gatsby page but not inside class componentGraphQL 查询适用于 Gatsby 页面,但不适用于类组件
【发布时间】:2019-12-27 22:41:00
【问题描述】:

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

我的项目结构如下:

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

我有一个名为about(棱镜单页类型)的页面组件,并设置了一些组件来“填充”这个页面(为了更好的可读性而进行了清理)。

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 页面组件的底部。它就像一个魅力和预期的那样工作。

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

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 查询片段,但不确定这是正确的用例还是只是一个愚蠢的初学者错误......

【问题讨论】:

    标签: reactjs graphql gatsby prismic.io


    【解决方案1】:

    那是因为你不能在你的组件中使用这样的 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
    

    希望对您有所帮助!

    【讨论】:

    • 谢谢 Logan Blangenois 和 ksav。这就像魅力一样,完美地解释了它。赞赏。
    【解决方案2】:

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

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

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

    // 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 docs.中阅读有关使用片段的更多信息

    【讨论】:

    • 感谢 Caleb Barnes,很好的解释。真的很感激。
    【解决方案3】:

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

    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>
              )
            }}
          />
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-09
      • 2020-07-19
      • 2020-08-21
      • 2021-08-14
      • 2018-11-10
      • 1970-01-01
      • 2017-10-03
      • 2011-05-20
      相关资源
      最近更新 更多