Слизняк Гэтсби сломан - PullRequest
0 голосов
/ 20 апреля 2020

Я создаю блог на своем сайте Гэтсби. Когда я перехожу к блогу на моем веб-сайте, содержимое загружается. Но когда я скопирую и вставлю URL-адрес блога прямо туда go, содержимое не загрузится. Просто шаблон загрузится. Вот 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
    })
  }
}

1 Ответ

1 голос
/ 21 апреля 2020

Вы используете dangerouslySetInnerHTML для компонента Text, который является абзацем styled-component. Проблема в том, что после добавления содержимого вы получаете p из содержимого, вложенного в этот элемент p. Это нестандартная разметка, и поэтому браузеры должны преобразовать ее в разборчивую разметку.

Таким образом, этот вид разметки <p><p></p></p> часто будет отображаться как <p></p><p></p>.

This на самом деле именно то, что происходит в вашем случае. Я позволил себе найти репозиторий GitHub для этого проекта и провел следующий эксперимент:

Я построил проект и искал родительский элемент p в сгенерированном Gatsby html. Вот оно:

nested p elements can be found on the generated html

Абзац с классом blog__Text... является вашим стилевым компонентом p, и вы можете ясно видеть, что он содержит другие элементы p который является нестандартным.

Затем я открыл этот файл в веб-браузере и проверил сгенерированную разметку:

Browser un-nesting nested p elements

... Сюрприз! Ваш компонент Text теперь пуст. Браузер, не зная ничего лучшего, выберет для удаления его содержимое и добавит его прямо рядом с ним. После повторной визуализации компонента он не будет содержать ничего. Поскольку это происходит за пределами React, компонент не будет повторно обработан новым содержимым, поскольку React не знает, что это произошло.


Если вы ограничите скорость своего соединения и попытаетесь получить доступ к странице, которую вы действительно может видеть содержимое в течение некоторого времени, пока страница загружена не полностью. Это происходит потому, что Гэтсби сначала выводит чистый html в браузер, прежде чем React вступит во владение. Затем вы кратко видите испорченное html представление вашей страницы до тех пор, пока компонент не будет отрисован, и все не встанет на свои места.

Решение

Как вы уже догадались, вам не следует вкладывать p элементов. Вместо этого вы должны использовать dangerouslySetInnerHTML в родительском div для вашего контента.

Вместо:

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

Использование:

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

Я пробовал именно это и все работает как положено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...