【问题标题】:Gatsby slug broken盖茨比蛞蝓断了
【发布时间】:2020-04-20 20:27:41
【问题描述】:

我正在我的 Gatsby 网站上建立一个博客。当我从我的网站导航到博客时,内容会加载。但是当我复制并粘贴博客的网址直接去那里时,内容将无法加载。只会加载模板。这是网址: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
    })
  }
}

【问题讨论】:

  • 您正在检索一个 null 值,该值在您的请求中生成 404 (/blog/nulll)。查看检查器中的网络选项卡。我需要更多信息,但是,您的查询似乎有误。如果您提供更多信息(例如您的查询),我会尝试正确回答您的问题。
  • 谢谢。我刚刚更新了节点文件

标签: reactjs gatsby


【解决方案1】:

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

这样,&lt;p&gt;&lt;p&gt;&lt;/p&gt;&lt;/p&gt; 这种标记通常会被渲染为&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;

这实际上正是您的情况。我冒昧地为这个项目找到了 GitHub 存储库并进行了以下实验:

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

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

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

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


如果您限制连接速度并尝试访问页面,您实际上可以在页面未完全加载时看到内容一段时间。这是因为 Gatsby 在 React 接管之前首先将纯 html 输出到浏览器。然后,您会短暂地看到页面的损坏的 html 表示,直到组件被渲染并且一切都崩溃了。

解决方案

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

代替:

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

用途:

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

我试过了,一切都按预期工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-30
    • 2016-06-02
    • 2021-04-04
    • 2014-04-02
    • 2016-07-22
    • 2011-02-09
    • 2013-05-27
    • 1970-01-01
    相关资源
    最近更新 更多