如何在容器类组件中使用 GraphQL 查询
Posted
技术标签:
【中文标题】如何在容器类组件中使用 GraphQL 查询【英文标题】:How to use GraphQL queries in a container class component 【发布时间】:2019-03-17 18:56:32 【问题描述】:??????
我当前的 GatsbyJS 项目是一个带有轮播和其他内容的单页浏览器。
背景
旋转木马应包含有关某些产品的信息。我的目标是通过遍历所有降价文件来让轮播自行构建,并在文件顶部选择具有以下三行的文件:
---
type: product
---
所以我创建了一个CarouselContainer
(类组件)和一个Carousel
组件(功能组件)。 Container 应该通过 GraphQL 查询加载 markdown,并将生成的 products 对象传递给它的嵌套组件。然后组件应该映射到对象上并创建轮播。
但也有其他用于菜单列表、文本模式等的降价文件。他们有type: page
。我认为准备一些 GraphQL 查询将是解决方案。但结果却比预想的要难……
容器组件是类组件,所以无法在里面直接调用查询(https://github.com/gatsbyjs/gatsby/issues/3991#issuecomment-364939030)。
然后我认为将多个查询放入pages/index.js
可能是解决方案。
export const indexQuery = graphql`
query IndexQuery
allMarkdownRemark(filter: frontmatter: type: eq: "page")
edges
node
frontmatter
title
text
`
export const productsQuery = graphql`
query ProductsQuery
allMarkdownRemark(filter: frontmatter: type: eq: "product")
edges
node
id
frontmatter
title
content
`
再次没有。使用 GraphQL 片段应该是一个解决方案...
Q谁能告诉我如何为此目的准备片段和/或有另一个想法如何将降价内容直接放入我的容器中?
感谢阅读。
【问题讨论】:
【参考方案1】:你离得不远了。 GraphQL 支持在同一个查询中查询多个离散节点:
export const query = graphql`
products: allMarkdownRemark(
filter: frontmatter: type: eq: "product"
)
edges
# ...
pages: allMarkdownRemark(
filter: frontmatter: type: eq: "pages"
)
edges
# ...
`
请注意,我使用别名在同一个 GraphQL 查询中使用不同的过滤器来获取相同的初始节点 (allMarkdownRemark
)。这将导致 data.products
和 data.pages
被传递到您的 default
导出的 React 组件中。
要清理它,您可以使用片段,允许您将 products
查询放在您的 Carousel
文件中:
在carousel.js
(或任何包含 Carousel 组件的文件中):
export const query = graphql`
fragment Products on Query
products: allMarkdownRemark(
filter: frontmatter: type: eq: "product"
)
edges
# ...
`
然后在你的页面文件中:
export const query = graphql`
pages: allMarkdownRemark(
filter: frontmatter: type: eq: "pages"
)
edges
# ...
...Products
`
注意:如果您使用的是 Gatsby 1.x,则需要将片段的 on Query
部分更改为 on RootQueryType
。
假设您使用的是 Gatsby v2,您也可以使用 StaticQuery 而不是将查询合并为一个。如果您的页面与产品轮播无关,这将特别有用。
import React from "react";
import graphql, StaticQuery from "gatsby";
class Carousel extends React.Component
// ...
export default props => (
<StaticQuery
query=graphql`
products: allMarkdownRemark(
filter: frontmatter: type: eq: "product"
)
edges
# ...
`
render=( products ) => <Carousel products=products ...props />
/>
);
【讨论】:
谢谢,成功了!使用别名的第一种方法效果很好。 StaticQuery 是首选方式。以前不知道该功能,因为我几周前开始使用 v1。 对于阅读此问题的其他人:我不能声称完全理解这一点,但只有当我删除render=
行中的
周围的 products
时,此解决方案才对我有用。在我的情况下,工作代码是render=( settings_query ) => <Interface settings=settings_query ...props />
。因此,如果您遇到问题,可能值得一试。
@RobinL 该位正在解构 props 对象的 product
属性。以上是关于如何在容器类组件中使用 GraphQL 查询的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据从反应组件传递到 Apollo graphql 查询?