Gatsby 查询在 graphql 编辑器中有效,但在反应代码中无效

Posted

技术标签:

【中文标题】Gatsby 查询在 graphql 编辑器中有效,但在反应代码中无效【英文标题】:Gatsby query works in graphql editor but not in react code 【发布时间】:2020-07-13 21:58:29 【问题描述】:

我正在使用 Gatsby 编写博客,并尝试根据用户点击的标签生成页面。

当用户点击标签时,他应该被重定向到显示带有该标签的文章列表的页面。

我创建了一个执行此操作的查询。但是,我的 GraphQL 查询在我的 GraphQL 编辑器中有效,但在我的反应代码中无效。它在代码中返回一个空数组,但是当我在 Graphql 编辑器中运行查询时,它会返回预期的结果。

import React from "react"
import ArticleCard from "../articleCard/ArticleCard"
import Pagination from "../pagination/Pagination"

import articlesStyles from "./Articles.module.scss"
import  useStaticQuery, graphql  from "gatsby"

const Articles = ( pageTitle ) => 
  const blogPosts = useStaticQuery(graphql`
    query($tag: String) 
      allMarkdownRemark(
        sort:  order: DESC, fields: [frontmatter___publish_date] ,
        filter:  frontmatter:  tags:  in: [$tag]   
      ) 
        nodes 
          frontmatter 
            title
            publish_date
            imageUrl
            author
            category
          
          fields 
            slug
          
          excerpt(pruneLength: 100)
        
      
    
  `)

  const nodes = blogPosts.allMarkdownRemark.nodes;
  console.log(nodes)
  return (
    <div className=articlesStyles.contentArea>
      <h1 className=articlesStyles.headerTitle>pageTitle</h1>
      <div className=articlesStyles.articles>
        nodes.map(node => 
          return (
            <ArticleCard
              key=node.id
              ...node.frontmatter
              excerpt=node.excerpt
              slug=node.fields.slug
            />
          )
        )
      </div>
      <Pagination />
    </div>
  )


export default Articles

【问题讨论】:

“已知限制 useStaticQuery 不接受变量” gatsbyjs.org/docs/use-static-query/#known-limitations 您是否为每个标签创建一个页面? 是的。不过问题已经解决了。 【参考方案1】:

正如 cmets 中提到的,你 can't use variables in a staticQuery。

但是,这可能会在未来发生变化,因为许多人偶然发现了这个限制,并且有 work in progress 提供“动态查询”。

与此同时,您可以在 gatsby-node.js 中的查询和createPage API 使用的模板中使用变量。因此,在您的情况下,您可以为 gatsby-node.js 中的所有标签生成所有页面,并且仍然使用相同的 article.js 作为组件模板。

见:https://www.gatsbyjs.org/docs/adding-tags-and-categories-to-blog-posts/

【讨论】:

【参考方案2】:

正如@xadm 和@ksav 在他们的cmets 中指出的那样:

“已知限制 useStaticQuery 不接受变量”

这里作为一种解决方法

查询所有博客,然后使用Array.prototype.filter() 获取您需要的博客:

// ...
  const blogPosts = useStaticQuery(graphql`
    query 
      allMarkdownRemark(
        sort:  order: DESC, fields: [frontmatter___publish_date] 
        // you can't filter here
      ) 
        nodes 
          frontmatter 
            title
            publish_date
            imageUrl
            author
            category
          
          fields 
            slug
          
          excerpt(pruneLength: 100)
        
      
    
  `)

// Get all blogs
const  blogPosts:  allMarkdownRemark:  edges    = props;

// filter the blogs
const yourFilteredTag = edges.filter(
  el => el.node.childMarkdownRemark.frontmatter.tag === yourTagVariable);

// Now you can get the filtered list of blogs
console.log(yourFilteredTag);

// ...

编辑

正如@Albert Skibinski 所说,此解决方案不可扩展。 gatsby-node.js 中的上下文可能是您的用例中更好的解决方案。

我描述的 Array.prototype.filter() 解决方案应该保留给 context 变量不可用的组件,并且您可以确保数组的大小不会增长过大。

【讨论】:

这会在每次使用该组件时查询所有篇博文,这会对性能产生负面影响,并且不是真正可扩展的。

以上是关于Gatsby 查询在 graphql 编辑器中有效,但在反应代码中无效的主要内容,如果未能解决你的问题,请参考以下文章

使用 Graphql 和 gatsby-source-filesystem 查询文件夹

如何在 Gatsby 中根据其他字段删除 GraphQL 字段?

如何在 graphQL 中获取 Gatsby 页面 HTML

Gatsby:graphql 查询中的 gatsby-source-graphql 和 gatsby-plugin-sharp

单个 GraphQL 查询中的多个源 (Gatsby)

Gatsby 和 GraphQL - 如何在查询中过滤数组