简体   繁体   English

在 GraphQL 查询模板中使用 React 属性(字符串)

[英]Use a React prop (string) in GraphQL query template

I am making a reusable component in a Gatsby blog to go at the end of blog articles which takes the authorName of the article, and renders an 'About the Author' section, pulling the info from the author's bio stored elsewhere on the site.我在 Gatsby 博客中制作了一个可重用组件到 go 在博客文章的末尾,该组件采用文章的作者姓名,并呈现“关于作者”部分,从存储在网站其他地方的作者生物中提取信息。

I have made the component which works when the authorName is hard coded as a string, but I am stuck on how to get the author name from the article component (passed as props.author) into the GraphQl query.我已经制作了当 authorName 被硬编码为字符串时可以工作的组件,但是我被困在如何从文章组件(作为 props.author 传递)中获取作者姓名到 GraphQl 查询中。

I can confirm that: 1. The prop author is being passed correctly and console logs exactly right 2. The correct bio information and profile image is being pulled from the team bios according to the hard coded string author name我可以确认: 1. 正确传递了道具作者,控制台日志完全正确 2. 根据硬编码字符串作者姓名从团队简历中提取了正确的个人信息和个人资料图片

The missing link is to replace the hardcoded author name string with props.author缺少的链接是用 props.author 替换硬编码的作者姓名字符串

Thanks in advance for your help;在此先感谢您的帮助; I've reviewed similar questions and can't find the answer.我已经查看了类似的问题,但找不到答案。

This is my component:这是我的组件:

AboutAuthor.js关于作者.js

import React from "react";
import { StaticQuery, graphql } from "gatsby";
import Img from "gatsby-image";

export default (props) => (
  <div>
    <StaticQuery
      query={graphql`
        query {
          copy: markdownRemark(
            frontmatter: { name: { eq: "need to replace this string with props.author" } }
          ) {
            html
            frontmatter {
              name
              profileImage {
              childImageSharp {
                fluid(maxWidth: 800) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
            }
          }
        }
      `}

      render={data => (
        <React.Fragment>
          <p>Testing Name: {props.author}</p> // testing the author name is passed ok, will be removed
          <Img
            fluid={data.copy.frontmatter.profileImage.childImageSharp.fluid}
            alt=""
          />
          <div>
            <span>
              {data.copy.frontmatter.name}
            </span>
            <div
              dangerouslySetInnerHTML={{ __html: data.copy.html }}
            />
          </div>
        </React.Fragment>
      )}
    />
  </div>
);

Check out the docs for How StaticQuery differs from page query查看文档了解StaticQuery 如何与页面查询不同

StaticQuery can do most of the things that page query can, including fragments. StaticQuery 可以做页面查询可以做的大部分事情,包括片段。 The main differences are:主要区别在于:

  • page queries can accept variables (via pageContext) but can only be added to page components页面查询可以接受变量(通过 pageContext)但只能添加到页面组件
  • StaticQuery does not accept variables (hence the name “static”), but can be used in any component, including pages StaticQuery 不接受变量(因此称为“静态”),但可以在任何组件中使用,包括页面
  • StaticQuery does not work with raw React.createElement calls; StaticQuery 不适用于原始 React.createElement 调用; please use JSX, eg <StaticQuery />请使用 JSX,例如<StaticQuery />

You can't do string interpolation or anything like that in static queries.您不能在 static 查询中进行字符串插值或类似的操作。 The reason being that the static query needs to be known at build time.原因是在构建时需要知道 static 查询。 That's when it's executed.那是它被执行的时候。 It runs when you're building the site, not when the site is live.它在您构建站点时运行,而不是在站点运行时运行。 That's the static part of not just the StaticQuery, but Gatsby in general.那是 static 的一部分,不仅是 StaticQuery,而且是一般的 Gatsby。 PageQueries may not have the 'static' in them, but they, too, run a build time. PageQueries 中可能没有“静态”,但它们也运行构建时间。 The only difference is that they do allow for the use of arguments, be it in a different way than you're trying to do it here.唯一的区别是它们确实允许使用 arguments,但与您在这里尝试的方式不同。

If this is on some automatically generated page using the createPages API, you should pass some identifier down to the page, which it can then use in a PageQuery to fetch the data.如果这是在使用createPages API 自动生成的页面上,您应该将一些标识符向下传递到页面,然后它可以在 PageQuery 中使用它来获取数据。 From what I can tell here, this doesn't look like it's your page element.据我所知,这看起来不像是您的页面元素。 Is this the bottom of the blogpost where you show some details on the author?这是博客文章的底部,您在其中显示了作者的一些详细信息吗? It looks like you have a separate entity for your authors, and for your blog pages.看起来您的作者和博客页面都有一个单独的实体。 That's good.那挺好的。 One way to pull this off is by making sure you query all necessary information in your PageQuery.实现这一目标的一种方法是确保在 PageQuery 中查询所有必要的信息。 If you have the data in your page component, you can simply pass it down to its children.如果您的页面组件中有数据,您可以简单地将其传递给它的子组件。 You just need to get all the necessary identifiers to the PageComponent using the context.您只需要使用上下文获取 PageComponent 的所有必要标识符。 This is how it's shown in the Gatsby docs:这是它在 Gatsby 文档中的显示方式:

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  const blogPostTemplate = path.resolve(`src/templates/blog-post.js`)

  return graphql(`
    query loadPagesQuery ($limit: Int!) {
      allMarkdownRemark(limit: $limit) {
        edges {
          node {
            frontmatter {
              slug
            }
          }
        }
      }
    }
  `, { limit: 1000 }).then(result => {
    if (result.errors) {
      throw result.errors
    }

    result.data.allMarkdownRemark.edges.forEach(edge => {
      createPage({
        path: `${edge.node.frontmatter.slug}`,
        component: blogPostTemplate,
        context: {
          // You need the something to query the author by, and something to query
          // the blog post by.
          author: edge.node.frontmatter.authorId, // or whatever you use to identify authors
          slug: edge.node.frontmatter.slug
        },
      })
    })
  })
}

Notice the two variables passed inside the context object.注意在上下文 object 中传递的两个变量。 Now inside your page element, you have these two variables that you can pass to your query.现在在您的页面元素中,您可以将这两个变量传递给您的查询。 The $autorId variable, and the $slug variable. $autoId 变量和 $slug 变量。 On the blog page you will need the blog post contents, but I'm sure you already have that part taken care of, as well as the author details to show the info on the author.在博客页面上,您将需要博客文章内容,但我确信您已经处理了该部分,以及作者详细信息以显示有关作者的信息。 In the PageQuery you can simply ask for two entities.在 PageQuery 中,您可以简单地请求两个实体。 One for the blogpost, the other for the author.一个用于博文,另一个用于作者。

Thanks to all the above answers;感谢以上所有答案; I didn't have success with my limited GraphQL knowledge and at this stage it's not something I want to dive into - I only have one use case for GraphQL.我有限的 GraphQL 知识并没有成功,在这个阶段,我不想深入研究 - 我只有一个 GraphQL 的用例。

So I dived into the docs some more and found this:https://www.gatsbyjs.org/docs/gatsby-config/#mapping-node-types which is working perfectly and is very simple to implement and is designed for the exact reason I needed it (blog author bio information).所以我深入研究了一些文档,发现了这个:https://www.gatsbyjs.org/docs/gatsby-config/#mapping-node-types ,它运行良好,实现起来非常简单,专为精确而设计我需要它的原因(博客作者生物信息)。

I regret not finding this earlier and preventing an unnecessary question but I hope this help someone in the future.我很遗憾没有早点找到这个并防止不必要的问题,但我希望这对将来的某人有所帮助。

Thanks again.再次感谢。

Since you are using template string, you can add variable like this ${variableName}.由于您使用的是模板字符串,因此您可以添加像 ${variableName} 这样的变量。 I hope this should work:我希望这应该有效:

query={graphql`
        query {
          copy: markdownRemark(
            frontmatter: { name: { eq: ${props.author} } }
          ) {
            html
            frontmatter {
              name
              profileImage {
              childImageSharp {
                fluid(maxWidth: 800) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
            }
          }
        }
      `}

Thanks谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM