Исчезает HTML при первом посещении страницы только с использованием пользовательского интерфейса Gatsby и Material - PullRequest
0 голосов
/ 13 февраля 2020

У меня есть блог Gatsby с компонентами Material UI, извлекающими файлы уценки с помощью GraphQL.

В разработке все отлично работает. Однако в производственной среде (gatsby build && gatsby serve) HTML либо не отображается, либо очень быстро исчезает после загрузки страницы, когда страница является первой загруженной страницей. Если я перехожу на другую страницу и возвращаюсь снова, она загружается правильно.

Интересный момент: когда я делаю компонент Typography variant="h6", он работает нормально, но variant="body1" или нет variant не удается правильно загрузить , Это заставляет меня думать, что это связано с тегом <p>.

Мой контент извлекается из файлов .md с помощью GraphQL и анализируется с помощью компонента Material-UI, например, <Typography align={props.align} dangerouslySetInnerHTML={{ __html: props.body }} />

Это элемент из инспектора при загрузке первой страницы, показывающий пустой DOM:

<div class="MuiGrid-root jss176 MuiGrid-item MuiGrid-grid-xs-12 MuiGrid-grid-sm-6" style="background:#e0e0e0">
<p class="MuiTypography-root MuiTypography-body1 MuiTypography-alignJustify"></p>
</div>

То, что я пробовал:

  1. Изменение variant типографии (как выше)
  2. Обход компонента шаблона и вставка HTML прямо в страницу (без изменений)
  3. Замена dangerouslySetInnerHTML на строку (без изменений)
  4. Внедрение HTML прямо в типографику без опасения. SetInner HTML (визуализирует raw HTML отлично)
  5. Смена браузера (без изменений)
  6. Очистить кеш, удалить node_modules, gatsby clean перестроить, et c (без изменений)

Вот один пример компонентов моего шаблона:


function ImageBoxLeft(props) {
  const theme = useTheme();
  const classes = useStyles();
  return (
    <Grid className={classes.root} container spacing={0}>
      {props.title && (
        <Grid item xs={12}>
          <Typography align="center" className={classes.title} component="h2" variant="h2">{props.title}</Typography>
        </Grid>
      )}
      <Grid component={Img} fluid={props.image} className={classes.image} item xs={12} sm={6} />
      <Grid className={classes.text} style={{ background: props.scheme2 ? theme.palette.scheme2.card : theme.palette.scheme1.card  }} item xs={12} sm={6}>
        <Typography align={props.align} dangerouslySetInnerHTML={{ __html: props.body }} />
      </Grid>
    </Grid>
  )
}

А вот пример страницы сайта:

import React, { Fragment } from "react";
import { StaticQuery, graphql } from "gatsby";
import { ImageBoxLeft } from 'components/ImageBox'
import CardSection from 'components/CardSection'
import EmailIcon from '@material-ui/icons/MailOutline';

const buttons = [
  {
    text: 'Enquire about managing risk for your team',
    to: '/contact',
    icon: <EmailIcon />
  },
]

function About() {
  return (
    <Fragment>
      <StaticQuery
        query={graphql`
        query {
          image1: file(relativePath: { eq: "img/general/home_main.jpg" }) {
            childImageSharp {
              fluid(maxWidth: 900, maxHeight: 570) {
                ...GatsbyImageSharpFluid_withWebp
              }
            }
          }
          about: markdownRemark(frontmatter: { name: { eq: "about" } }) {
            html
            frontmatter {
              title
            }
          }
        }
      `}
        render={data => (
          <Fragment>
            <CardSection
              title="About Us"
              buttons={buttons}
              scheme2
            >
              <ImageBoxLeft
                align="justify"
                image={data.image1.childImageSharp.fluid}
                body={data.about.html}
                scheme2
              />
            </CardSection>
          </Fragment>
        )}
      />
    </Fragment>
  )
}

export default About

И мои посылки:

"dependencies": {
    "@material-ui/core": "^4.9.2",
    "@material-ui/icons": "^4.9.1",
    "@material-ui/styles": "^4.9.0",
    "gatsby": "^2.19.14",
    "gatsby-image": "^2.2.34",
    "gatsby-plugin-canonical-urls": "^2.1.13",
    "gatsby-plugin-feed": "^2.3.19",
    "gatsby-plugin-google-analytics": "^2.1.23",
    "gatsby-plugin-html-attributes": "^1.0.5",
    "gatsby-plugin-material-ui": "^2.1.6",
    "gatsby-plugin-preconnect": "^1.0.3",
    "gatsby-plugin-react-helmet": "^3.1.22",
    "gatsby-plugin-robots-txt": "^1.4.0",
    "gatsby-plugin-sharp": "^2.2.32",
    "gatsby-plugin-sitemap": "^2.2.19",
    "gatsby-plugin-web-font-loader": "^1.0.4",
    "gatsby-plugin-webpack-bundle-analyzer": "^1.0.5",
    "gatsby-remark-copy-linked-files": "^2.1.28",
    "gatsby-remark-images": "^3.1.34",
    "gatsby-source-filesystem": "^2.1.39",
    "gatsby-transformer-remark": "^2.6.38",
    "gatsby-transformer-sharp": "^2.3.6",
    "react": "^16.10.2",
    "react-dom": "^16.10.2",
    "react-helmet": "^5.2.1",
    "react-twitter-embed": "^3.0.3"
  }

1 Ответ

1 голос
/ 13 февраля 2020

Таким образом, решение состоит в том, чтобы сделать компонент Typography <div>, чтобы избежать вложенных тегов <p>, которые были взяты из комментария Лукаса Араужо выше, а также добавить ключ в соответствии с этим https://github.com/gatsbyjs/gatsby/blob/717ee6eede217189820af2a644706a257e0a9623/packages/gatsby/cache-dir/default-html.js#L19

А это https://github.com/gatsbyjs/gatsby/issues/2750#issuecomment -341765585

И это https://github.com/facebook/react/issues/5479

Итак, мой новый рабочий компонент выглядит так:

import React from "react";
import { makeStyles } from '@material-ui/core/styles';
import {
  Box,
  Typography
} from '@material-ui/core';

const useStyles = makeStyles(theme => ({
  root: {
    padding: theme.spacing(0),
    margin: theme.spacing(0)
  }
}));

function ArticleBody(props) {
  const classes = useStyles();
  return (
    <Box className={classes.root}>
      <Typography
        key={props.key}
        color={props.color ? props.color : "default"}
        align={props.align ? props.align : 'justify'}
        variant={props.variant ? props.variant : 'body1'}
        component="div"
        dangerouslySetInnerHTML={{ __html: props.content }}
      />
    </Box>
  )
}

export default ArticleBody

Спасибо за помощь, Лукас Араужо!

...