盖茨比子弹碎

问题描述 投票:0回答:1

我正在Gatsby网站上建立博客。当我从网站中导航到博客时,将加载内容。但是,当我将博客的URL复制并粘贴到此处后,该内容将不会加载。仅模板将加载。这是网址:https://www.squarepatch.io/Instructions/blog/

不确定哪个文件引起了这个问题,但是这是我的模板文件:

import React from "react";
import { graphql, Link } from "gatsby";
import styled from "styled-components"
import './item.css'
import Layout from "../components/layout";


class Blog extends React.Component {

  render() {
    const item = this.props.data.markdownRemark
    const siteTitle = this.props.data.site.siteMetadata.title

    return (

      <Layout location={this.props.location} title={siteTitle}>
        <Article>
          <Heading>
            <Title>{item.frontmatter.title}</Title>
            <Date>{item.frontmatter.date}</Date>
          </Heading>
          <Body>
            <Text dangerouslySetInnerHTML={{ __html: item.html }} />
          </Body>

          <Closing>
            <Questions>🙋Have a question / comment / concern? Feel free to <Link to='/contact' style={{ fontWeight: `500`, fontStyle: `italic` }}>reach out!</Link></Questions>
          </Closing>
        </Article>
      </Layout>

    )
  }
}

export default Blog;

export const pageQuery = graphql`
  query BlogBySlug($slug: String!) {
    site {
      siteMetadata {
        title
      }
    }
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      fields {
        slug
      }
      frontmatter {
        title
        date
      }
    }
  }
`

这里是节点文件

const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions

  const item = path.resolve(`./src/templates/item.js`)
  const blog = path.resolve(`./src/templates/blog.js`)
  return graphql(
    `
      {
        allMarkdownRemark(
          sort: { fields: [frontmatter___date], order: DESC }
          limit: 1000
        ) {
          edges {
            node {
              fields {
                slug
              }
              frontmatter {
                title
                posttype
              }
            }
          }
        }
      }
    `
  ).then(result => {
    if (result.errors) {
      throw result.errors
    }

    // Create item posts pages.
    const posts = result.data.allMarkdownRemark.edges

    posts.forEach((post, index) => {
      const previous = index === posts.length - 1 ? null : posts[index + 1].node
      const next = index === 0 ? null : posts[index - 1].node



      if (post.node.frontmatter.posttype === 'product') { //product post

      createPage({
        path: post.node.fields.slug,
        component: item,
        context: {
          slug: post.node.fields.slug,
          previous,
          next,
        },
      })

    } else { //blog post
      createPage({
        path: post.node.fields.slug,
        component: blog,
        context: {
          slug: post.node.fields.slug,
          previous,
          next,
        },
      })


    }


    })

    return null
  })
}

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value
    })
  }
}

reactjs gatsby
1个回答
0
投票

您正在使用dangerouslySetInnerHTML段落的Text组件上使用styled-component。问题在于,一旦添加了内容,您最终将从嵌套在此p元素内的内容得到p。这是非标准标记,因此浏览器必须将其转换为可解析的标记。

以这种方式,这种标记<p><p></p></p>通常会呈现为<p></p><p></p>

这实际上就是您的情况。我可以自由地为此项目找到GitHub存储库并运行以下实验:

我构建了projet,并在生成的Gatsby html中搜索了父p元素。这是:

nested p elements can be found on the generated html

带有blog__Text...类的段落是您的样式组件p,您可以清楚地看到它包含其他p个非标准元素。

然后,我使用网络浏览器打开此文件,并检查了生成的标记:

Browser un-nesting nested p elements

...惊喜!您的Text组件现在为空。浏览器不知道会更好地选择取消嵌套其内容并将其附加在其旁边。组件重新渲染后,将不包含任何内容。由于这是在React边界之外发生的,因此该组件不会被新的内容重新水化,因为React不知道这是刚刚发生的。


如果限制连接速度并尝试访问该页面,则在页面未完全加载时,您实际上可以看到内容一段时间。发生这种情况是因为Gatsby在React接手之前首先将纯HTML输出到浏览器。然后,您会短暂看到页面的html表示残破,直到呈现该组件并且一切正常为止。

解决方案

您可能已经猜到了,您不应该嵌套p元素。相反,您应该在父div上使用dangerouslySetInnerHTML作为内容。

而不是:

 <Body>
     <Text dangerouslySetInnerHTML={{ __html: item.html }} />
 </Body>

用途:

 <Body>
     <div dangerouslySetInnerHTML={{ __html: item.html }} />
 </Body>

我尝试过,一切都按预期进行。

© www.soinside.com 2019 - 2024. All rights reserved.