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

标签 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 片段应该是一个解决方案……

有人可以告诉我如何为此目的准备片段和/或有其他想法如何将 Markdown 内容直接放入我的容器中吗?

感谢阅读。

最佳答案

你离得不远了。 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 组件中。

要清理它,您可以使用片段,允许您在 Carousel 文件中定位您的 products 查询:

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

关于javascript - 如何在容器类组件中使用 GraphQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52781291/

相关文章:

javascript - 检查是否定义了 javascript 对象/属性

javascript - jQuery 动画 img margin-top

reactjs - react-native 对 Web 开发和移动开发都有好处

javascript - 访问绑定(bind)到底层类的 DOM 节点和函数

graphql - 如何使用 GraphQL 突变在解析器中添加递归逻辑?

javascript - 如何在js中使用原型(prototype)继承

javascript - Charts.js折线图,如果数据相同,如何隐藏y轴开始和结束标签

javascript - 使用 React 可视化算法——我做错了什么?

javascript - 为什么 Relay Modern QueryRenderer 渲染 Prop 未定义?

graphql - GraphQL 的 ID 标量有什么意义?