如何在容器类组件中使用GraphQL查询

时间:2018-10-12 14:06:25

标签: javascript reactjs graphql gatsby

我当前的 GatsbyJS 项目是一个带有轮播和其他内容的单页寻呼机。

背景

转盘上应装有有关某些产品的信息。我的目标是让轮播通过遍历所有markdown文件来构建自身,并在文件顶部选择以下三行的文件:

---
type: product
---

因此,我创建了一个CarouselContainer(类组件)和一个Carousel组件(功能组件)。容器应通过GraphQL查询加载markdown并将结果产品对象传递给其嵌套组件。然后,组件应在对象上映射并创建轮播。

但是,还有其他用于菜单列表,文本模式等的markdown文件。他们有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 个答案:

答案 0 :(得分:2)

距离您不太远。 GraphQL支持在同一查询中查询多个离散节点:

export const query = graphql`
  {
    products: allMarkdownRemark(
      filter: { frontmatter: { type: { eq: "product" } } }
    ) {
      edges {
        # ...
      }
    }

    pages: allMarkdownRemark(
      filter: { frontmatter: { type: { eq: "pages" } } }
    ) {
      edges {
        # ...
      }
    }
  }
`

请注意,我已经使用别名在同一GraphQL查询中使用单独的过滤器来获取同一初始节点(allMarkdownRemark)。这将导致data.productsdata.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} />}
  />
);