【问题标题】:Gatsby query works in graphql editor but not in react codeGatsby 查询在 graphql 编辑器中有效,但在反应代码中无效
【发布时间】: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

【问题讨论】:

标签: javascript reactjs graphql gatsby


【解决方案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 变量不可用的组件,并且您可以确保数组的大小不会增长过大。

    【讨论】:

    • 这会在每次使用该组件时查询所有篇博文,这会对性能产生负面影响,并且不是真正可扩展的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 2016-08-26
    • 2017-02-25
    • 2014-07-22
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多