【问题标题】:How do you split page templates into individual components, each querying data?您如何将页面模板拆分为单独的组件,每个组件都查询数据?
【发布时间】:2020-07-18 11:43:16
【问题描述】:

我在 Gatsby 中创建了一个博客文章模板。现在我想将页面分解为功能组件,每个组件都通过useStaticQuery 提取数据。

据我所知,Graphql 变量仅适用于页面查询,模板文字也不例外:

const Slideshow = props => {

  const data = useStaticQuery(
    graphql`
      query {
        contentfulPost(slug: { eq: "${ props.slug }" }) {
          images {
            title
            description
            sizes
          }
        }
      }
    `

   ...

}

如何让组件知道要查询哪些数据?

【问题讨论】:

    标签: javascript reactjs graphql gatsby


    【解决方案1】:

    组件本身不应进行任何查询。您应该将该部分抽象为模板。

    首先,使用gatsby-node.js 中的createPages API 生成带有模板的博客文章,类似于:

    ...
    createPage({
      path: `${entity.entityTranslation.entityUrl.path}`,
      component: path.resolve(`./src/templates/article.js`),
      context: {
        id: entity.entityTranslation.entityId,
        languageId: lang.toUpperCase(),
      },
    })
    ...
    

    您可以看到,在我的例子中,我将 ID 和语言 ID 传递给 article.js 中的模板查询:

    import React from "react"
    import { graphql } from "gatsby"
    import Layout from "../components/layout/layout"
    import ArticleFull from "../components/node/article-full";
    
    export default ({ data }) => {
    
      return (
        <Layout>
          <ArticleFull entity={data.drupal.nodeById.entityTranslation} />
        </Layout>
      )
    }
    
    export const query = graphql`
      query($id: String!, $languageId: Drupal_LanguageId!) {
        drupal {
          nodeById(id: $id) {
            ... on Drupal_NodeArticle {
              entityTranslation(language: $languageId) {
                ...ArticleFull
              }
            }
          }
        }
      }
    `;
    

    查询检索每篇文章的数据。在我的例子中,源是 Drupal,所以这个查询对于 Drupal 来说是非常具体的,但是你应该能够根据你的 graphql 数据来定制它。请注意我在这里如何使用片段 (ArticleFull)。

    我的实际组件是ArticleFull,看起来像这样:

    import React from "react";
    import "./article-full.scss"
    
    const ArticleFull = (props) => {
    
      return (
        <div className="article-full">
          <h1>{props.entity.entityLabel}</h1>
          <div className="article-body" dangerouslySetInnerHTML={{ __html: props.entity.body.processed }}></div>
        </div>
      )
    };
    
    export default ArticleFull;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-11
      • 2016-02-07
      • 2012-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多