使用静态查询在Gatsby组件中格式化Markdown HTML数据

时间:2020-08-10 14:33:47

标签: graphql components gatsby netlify-cms

我正在尝试使用GatsbyJS中带有静态查询的组件来显示来自markdown文件的html信息。当我打印数据时,会得到带有标签的原始HTML。

Curent result

我想在下面显示降价的标题和HTML文本。

components/contact.js

    import React from "react"
import { Link, StaticQuery, graphql } from "gatsby"

const Cont = ({ data }) => (
  <section className="home-banner">
    <h1 className="title">
      {data}
    </h1>
    <div className="description">
      {data}
    </div>
  </section>
)

export default function ContText() {
  return(
    <StaticQuery
      query={graphql`
        query MyQuery {
          markdownRemark(frontmatter: {template: {eq: "contact-page"}}) {
            html
            frontmatter {
              title
            }
          }
        }`
      }

      render={ data  => {

        return(
          <Cont

                data={data.markdownRemark.html}

          />
        )
       }
      }
    />
  )
}

有没有一种方法可以使用一个组件显示标题和文本,以及如何像原始页面一样将原始HTML更改为更清晰的文本数据。

 index-page.js

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

import Layout from "../components/layout"
import BlogListHome from "../components/blog-list-home"
import SEO from "../components/seo"
import Cont from "../components/contact"

export const pageQuery = graphql`
  query HomeQuery($id: String!){
        markdownRemark(id: { eq: $id }) {
      id
      html
      frontmatter {
        title
        tagline
        featuredImage {
          childImageSharp {
            fluid(maxWidth: 480, maxHeight: 380, quality: 80, srcSetBreakpoints: [960, 1440]) {
              ...GatsbyImageSharpFluid
            }
            sizes {
              src
            }
          }
        }
        cta {
          ctaText
          ctaLink
        }
      }
    }
  }
  `

const HomePage = ({ data }) => {
  const { markdownRemark } = data // data.markdownRemark holds your post data
  const { frontmatter, html } = markdownRemark
  const Image = frontmatter.featuredImage ? frontmatter.featuredImage.childImageSharp.fluid : ""
    return (
        <Layout>
      <SEO/>
      <div className="home-banner grids col-1 sm-2">
        <div>
          <h1 class="title">{frontmatter.title}</h1>
          <p class="tagline">{frontmatter.tagline}</p>
          <div className="description" dangerouslySetInnerHTML={{__html: html}}/>
        </div>
        <div>
          {Image ? (
            <Img
              fluid={Image}
              alt={frontmatter.title + ' - Featured image'}
              className="featured-image"
            />
          ) : ""}
        </div>
      </div>
      <div>
      <Cont/>
      </div>
      <BlogListHome/>
      <div>
      <h1> Recomendations go hear!</h1>
      </div>
        </Layout>
    )
}

export default HomePage

目前,我正在考虑创建2个组件,其中一个用于创建内容,但如果我不能更改HTML,则无关紧要。谢谢大家。

1 个答案:

答案 0 :(得分:0)

您正在正确检索数据。您的GraphQL看起来不错,可以正确地从markdown文件收集所有数据。

您缺少的是HTML标记中的compare_filesdangerouslySetInnerHTML是React在浏览器DOM中使用dangerouslySetInnerHTML的替代品。因此,将其应用于您的代码:

innerHTML

注意:<h1 className="title" dangerouslySetInnerHTML={{ __html: data }} /> 同样适用。因为您没有在其中包装任何东西,所以可以自行关闭<div>

之所以命名,是因为通常它可能会带来风险,因为它会使您的用户遭受跨站点脚本(XSS)攻击。理想情况下,您应该映射<h1>的每个响应,并根据它呈现一个已解析的标签,但就目前而言,因为在95%的情况下,它会按预期运行,而不会给用户带来任何风险。

您可以在React's official documentation上查看更多信息。