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

Gir*_*gar 4 javascript reactjs graphql gatsby

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

背景

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

---
type: product
---
Run Code Online (Sandbox Code Playgroud)

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

但是,还有其他用于菜单列表,文本模式等的markdown文件。他们有type: page。我认为准备一些GraphQL查询将是解决方案。但这却比预期的要困难得多。

容器组件是一个类组件,因此我无法直接在其中调用查询(https://github.com/gatsbyjs/gatsby/issues/3991#issuecomment-364939030)。

然后,我认为将多个查询放入pages/index.js可能是解决方案。

---
type: product
---
Run Code Online (Sandbox Code Playgroud)

再没有。使用GraphQL片段应该是一个解决方案...

有人可以告诉我如何为此目的准备片段和/或有另一个想法如何将降价内容正确放入我的容器中吗?

谢谢阅读。

cor*_*ard 6

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

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

    pages: allMarkdownRemark(
      filter: { frontmatter: { type: { eq: "pages" } } }
    ) {
      edges {
        # ...
      }
    }
  }
`
Run Code Online (Sandbox Code Playgroud)

请注意,我已经使用别名allMarkdownRemark在同一GraphQL查询中使用单独的过滤器来获取同一初始节点()。这将导致data.products并将data.pages其传递到default导出的React组件中。

要清理此问题,可以使用片段,使您可以productsCarousel文件中并置查询:

进入carousel.js(或任何包含“轮播”组件的文件):

export const query = graphql`
  fragment Products on Query {
    products: allMarkdownRemark(
      filter: { frontmatter: { type: { eq: "product" } } }
    ) {
      edges {
        # ...
      }
    }
  }
`
Run Code Online (Sandbox Code Playgroud)

然后在您的页面文件中:

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

    ...Products
  }
`
Run Code Online (Sandbox Code Playgroud)

注意:如果您使用的是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} />}
  />
);
Run Code Online (Sandbox Code Playgroud)