GraphQL 查询适用于 Gatsby 页面,但不适用于类组件
Posted
技术标签:
【中文标题】GraphQL 查询适用于 Gatsby 页面,但不适用于类组件【英文标题】:GraphQL query works in Gatsby page but not inside class component 【发布时间】: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 查询片段,但不确定这是正确的用例还是只是一个愚蠢的初学者错误......
【问题讨论】:
【参考方案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>
)
/>
);
【讨论】:
以上是关于GraphQL 查询适用于 Gatsby 页面,但不适用于类组件的主要内容,如果未能解决你的问题,请参考以下文章
Gatsby 查询在 graphql 编辑器中有效,但在反应代码中无效
如何在 graphQL 中获取 Gatsby 页面 HTML
gatsby-source-drupal 不显示 graphql 查询