在页面重载时,我的Gatsby.js页脚组件渲染了两次。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在页面重载时,我的Gatsby.js页脚组件渲染了两次。相关的知识,希望对你有一定的参考价值。
谢谢你花时间来看我的问题。我真的很感激任何帮助。
**更新:好的,我想我知道是什么导致了这个问题,但我不知道为什么。之前,在我的productsmerch页面,我的数据库中只有一个项目。在productsbeans页面,我有多个项目。在productsmerch页面上,当查询结果只有一个时,页脚不会显示两次。只要我在商品类别中添加了另一个项目,并且productsmerch有两个产品,在页面重新加载时,它也开始重复显示页脚。
为什么多次查询会对页面的渲染有影响?有什么办法可以解决这个问题?我打算尝试将graphql中的数据作为道具传递给allProducts组件,看看是否能解决这个问题。
我正在使用Gatsby.js和Strapi无头CMS来构建一个电子商务网站。在一个显示特定类别中所有产品的页面上,如果页面被重新加载,它将两次渲染页脚。这让人很困惑,因为当页面第一次渲染时,它是正常的,但只有在重新加载时才会这样做。如果网站从该特定页面加载,它也会显示两个页脚。一旦我导航到另一个页面并重新加载,第二个页脚就会消失。给我带来问题的这个页面有一个GraphQL查询。我有另一个页面,也有一个GraphQL查询,但它不这样做。这个页面中的某些东西导致了渲染中的问题。
我尝试过:在gatsby-node.js中,在createPages导出中,我曾尝试创建每个页面,并传递一个模板和 "type "的上下文,这样GraphQL查询就可以过滤页面所需的数据。我以为这样使用createPage可能会造成渲染问题。我也试过把Footer组件的内容去掉,直接放在layout.js中。我试过从页面中删除Layout组件,直接添加Header.js和Footer.js,还是一样的问题。我只在主机上遇到这个问题,而不是在本地主机上。是服务器端渲染的问题吗?这里有一个网站的链接,托管在gatsby cloud上,如果你点击其他页面并刷新,第二个页脚就会消失,但如果你点击回到这个页面,然后再刷新,第二个页脚又会弹出来。
https:/build-856af2e5-f049-46de-b6a5-9e11aa46a906.gtsb.ioproductsbeans。
createPage({
path: "/products/merch",
component: path.resolve(`src/templates/allproducts.js`),
context: {
type: "merch",
},
})
createPage({
path: "/products/beans",
component: path.resolve(`src/templates/allproducts.js`),
context: {
type: "beans",
},
})
所以我把每个页面都移动到Gatsby页面文件夹中。因此,我没有使用createPages来编程创建它们,而是通过创建一个产品文件夹,然后为每个类别添加一个新的页面,以传统的方式创建它们。但这并不能解决我的问题,因为我没有使用createPages,而是手动创建页面。
我不明白为什么页脚会加载两次,而页眉或我的layout.js中的主要组件却没有加载,它看起来是这样的。
import React from "react"
import PropTypes from "prop-types"
import { useStaticQuery, graphql } from "gatsby"
import Footer from "./Footer"
import Header from "./header"
import "./layout.css"
const Layout = ({ children }) => {
const data = useStaticQuery(graphql`
query SiteTitleQuery {
site {
siteMetadata {
title
}
}
}
`)
return (
<>
<Header siteTitle={data.site.siteMetadata.title} />
<main>{children}</main>
<Footer />
</>
)
}
Layout.propTypes = {
children: PropTypes.node.isRequired,
}
export default Layout
这里是Footer.js组件。
import React from "react"
import { Facebook, Instagram, Twitter } from "@material-ui/icons"
import styled from "styled-components"
const BottomNav = styled.footer`
border-top: 1px solid black;
position: sticky;
height: 15vh;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
font-family: Raleway;
text-transform: uppercase;
`
const BottomNavContainer = styled.div`
display: flex;
justify-content: space-between;
width: 200px;
margin-bottom: 0.3rem;
`
const Footer = () => {
return (
<BottomNav>
<BottomNavContainer>
<Facebook />
<Instagram />
<Twitter />
</BottomNavContainer>
<div>
© {new Date().getFullYear()},{` `} The Blank
</div>
</BottomNav>
)
}
export default Footer
这是重复页脚的页面的代码。
function Alert(props) {
return <MuiAlert elevation={6} variant="filled" {...props} />
}
const AllBeansPage = props => {
const products = props.data.allStrapiProduct.nodes
// const classes = useStyles()
const [open, setOpen] = React.useState(false)
const { addToCart } = useContext(CartContext)
const handleClick = () => {
setOpen(true)
}
const handleClose = (event, reason) => {
if (reason === "clickaway") {
return
}
setOpen(false)
}
return (
<Layout>
<SEO
title={
products[0].type.charAt(0).toUpperCase() + products[0].type.slice(1)
}
/>
<Fade in={true} timeout={{ enter: 2000, exit: 500 }}>
<AllProductsContainer>
<Container>
{products.map(product => (
<Slide
direction="left"
in={true}
mountOnEnter
unmountOnExit
timeout={{ enter: 1500, exit: 500 }}
>
<ProductCard key={product.id}>
<Link
key={product.id}
style={{}}
to={`products/${product.type}/${product.slug}`}
>
<ImageContainer>
{console.log(product.thumbnail.childImageSharp.fluid)}
<Img
key={product.id}
fluid={product.thumbnail.childImageSharp.fluid}
/>
</ImageContainer>
</Link>
<ProductContent>
<Typography
gutterBottom
variant="h5"
component="h1"
style={{
fontFamily: "Caveat",
fontSize: "clamp(22px, 3vw, 28px)",
}}
>
{product.name}
</Typography>
<Typography
variant="body2"
color="textSecondary"
style={{ fontSize: "clamp(12px, 1.5vw, 16px)" }}
>
{product.description.slice(0, 35)}...
</Typography>
<Link
key={product.id}
style={{}}
to={`products/${product.type}/${product.slug}`}
>
{" "}
<Typography
variant="subtitle1"
color="primary"
style={{ fontSize: "clamp(14px, 1.5w, 18px)" }}
>
Learn More
</Typography>
</Link>
</ProductContent>
<CardActionArea>
<CardActions
style={{
display: "flex",
justifyContent: "space-between",
}}
>
<Button
size="small"
color="primary"
onClick={() => {
addToCart(product, 1)
handleClick()
}}
style={{ fontSize: "clamp(12px, 1.5vw, 18px)" }}
>
Add To Cart
</Button>
<Typography
variant="body1"
style={{ fontSize: "clamp(12px, 1.5vw, 18px)" }}
>
{formatPrice(product.price_in_cents)}
</Typography>
</CardActions>
</CardActionArea>
</ProductCard>
</Slide>
))}
</Container>
</AllProductsContainer>
</Fade>
<Snackbar open={open} autoHideDuration={6000} onClose={handleClose}>
<Alert onClose={handleClose} severity="success">
Item successfully added to cart.
</Alert>
</Snackbar>
</Layout>
)
}
export default AllBeansPage
export const productQuery = graphql`
query allBeanQuery {
allStrapiProduct(filter: { type: { eq: "beans" } }) {
nodes {
strapiId
id
description
created_at
price_in_cents
name
slug
type
thumbnail {
childImageSharp {
fluid(quality: 100, maxWidth: 150, maxHeight: 150) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
`
好吧!我知道是什么原因导致了这个问题。所以这里是解决这个问题的方法。如果你使用的是GatsbyJS和CMS,如果你使用Material-UI,有时候在服务器上渲染东西会有问题。我认为是Material-UI中的某些东西导致了页面上的重渲染。基本上,在产品页面组件中,我将以下内容替换成了
<Button
onClick={() => {
addToCart(product, 1)
handleClick()
}}
style={{ fontSize: "clamp(12px, 1.5vw, 16px)" }}>ADD TO CART
</Button>
与
<div
onClick={() => {
addToCart(product, 1)
handleClick()
}}
style={{ fontSize: "clamp(12px, 1.5vw, 16px)" }}>ADD TO CART
</div>
然后它就工作了。因此,如果你在一个页面上得到两个相同的组件渲染,并且一切看起来都是正确的,只需仔细检查是否你使用的组件库导致了问题。
以上是关于在页面重载时,我的Gatsby.js页脚组件渲染了两次。的主要内容,如果未能解决你的问题,请参考以下文章