如何在容器类组件中使用 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.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 />
  />
);

【讨论】:

谢谢,成功了!使用别名的第一种方法效果很好。 StaticQuery 是首选方式。以前不知道该功能,因为我几周前开始使用 v1。 对于阅读此问题的其他人:我不能声称完全理解这一点,但只有当我删除 render= 行中的 周围的 products 时,此解决方案才对我有用。在我的情况下,工作代码是render=( settings_query ) =&gt; &lt;Interface settings=settings_query ...props /&gt;。因此,如果您遇到问题,可能值得一试。 @RobinL 该位正在解构 props 对象的 product 属性。

以上是关于如何在容器类组件中使用 GraphQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

如何在组件外调用 GraphQL

如何将数据从反应组件传递到 Apollo graphql 查询?

如何从组件中抽象出一个 graphQL 查询?

如何将变量添加到 GraphQL 文件查询

如何从另一个 React / ReactNative 组件触发 GraphQL 查询

GraphQL 查询适用于 Gatsby 页面,但不适用于类组件