我在gatsby develop和gatsby build生成的站点之间有一个不一致的行为问题。其结果是一个在开发中而不是生产中工作的网站。
我的网站摘要:
一个简单的类似博客的网站(个人简介,而不是博客帖子)。索引页是人员列表,该列表中的每一项都链接到该人的配置文件页面。
我正在使用盖茨比来构建这个站点。我的数据(个人简介)是托管在内容无头CMS上的条目。我正在使用盖茨比源-内容丰富源代码插件。
问题的高级描述
我无法在索引页面中调整配置文件列表项的顺序。唯一的行为,我的网站超越任何基本盖茨比教程是,我想随机化的配置文件列表在我的索引页面(给每个人一个公平的机会被列在顶端)。
gatsby build生成一个静态索引页,其中列表位于一个置换中。当在浏览器中加载时,ThumbList组件会在呈现时将这些项重新洗牌到另一个排列中,并且一些子元素在其他元素移动时没有得到适当的管理。例如,这会导致将图像与错误的名称配对。
密码
下面的代码为可读性做了一些总结。
src/pages/index.js:
import React from "react"
import Layout from "../components/layout"
import ThumbList from "../components/thumbList"
import { graphql } from "gatsby"
export default ({data}) => {
// people are called "creators" in the app
const creatorData = data.allContentfulCreator.edges
const shuffledData = shuffle(creatorData.slice(0))
return (
<Layout>
<ThumbList data={shuffledData} />
</Layout>
)
}
const shuffle = (a) => {
// Fisher-Yates randomized array in-place shuffle algo
// ...
return a
}
export const query = graphql`
{
allContentfulCreator {
edges {
node {
id
slug
name
bio {
id
bio
}
mainImage {
file {
url
}
}
}
}
}
}
`src/components/umbList.js:
import React from "react"
import { Link } from "gatsby"
// A list of creator profile links, with name and picture thumbnail
export default ({data}) => {
return (
<div>
<ul>
{
data.map(({node}) => {
const creator = node
const link = "/" + creator.slug
const image = "https:" + creator.mainImage.file.url
return (
<li key={creator.id}>
<Link to={link}>
{creator.name}
</Link>
<img src={image} />
</li>
)
})
}
</ul>
</div>
)
}gatsby build的结果是包含以下内容的index.html:
<ul>
<li>
<a href="/alice">
Alice
</a>
<img src="cdn.com/alice.jpg">
</li>
<li>
<a href="/bob">
Bob
</a>
<img src="cdn.com/bob.jpg">
</li>
<li>
<a href="/eve">
Eve
</a>
<img src="cdn.com/eve.jpg">
</li>
</ul>但是,当在浏览器中(通过gatsby serve或站点的部署版本)查看索引页时,live ThumbList组件再次对其呈现方法中的数据进行洗牌。
结果是重新呈现的html:
<ul>
<li>
<a href="/alice">
Bob
</a>
<img src="cdn.com/alice.jpg">
</li>
<li>
<a href="/bob">
Eve
</a>
<img src="cdn.com/bob.jpg">
</li>
<li>
<a href="/eve">
Alice
</a>
<img src="cdn.com/eve.jpg">
</li>
</ul>这里只有文本节点被重新排列以匹配新的顺序(由记录数组顺序的控制台确认),但是链接和图像元素仍然停留在静态构建中的位置。现在名称、图像和链接都被置乱了。
还有两件事要注意:
gatsby develop一起工作。我想这是因为在开发过程中,index.html是在没有静态内容的情况下生成的--允许从一开始就完全控制DOM,而不需要静态脚手架来混淆它。(可读性的缩写)
<ul>
<li key="165e2405">
<GatsbyLink to="/bob">
Bob
</GatsbyLink>
<img src="cdn.com/bob.jpg"></img>
</li>
<li key="067f9afc">
<GatsbyLink to="/eve">
Eve
</GatsbyLink>
<img src="cdn.com/eve.jpg"></img>
</li>
<li key="ca4b82bf">
<GatsbyLink to="/alice">
Alice
</GatsbyLink>
<img src="cdn.com/alice.jpg"></img>
</li>
</ul>我的问题
/static/d/556/path---index-6a9-L7r5Sntxcv3RUIoHYIR3Qqm9Jmg.json)获得,但是我想动态地对数据进行洗牌,并在呈现时重新排列DOM。盖茨比不可能这么做吗?我是否需要在构建过程中放弃预取数据,只需要考虑一个动态组件并通过componentDidMount中的内容API获取数据?发布于 2020-01-07 16:50:15
我最近一直在为这件事苦苦挣扎!
我的解决方案是使用ReactDOM的呈现方法在父组件挂载后呈现被洗牌的内容:
import React, { useRef, useEffect } from "react";
import { render } from "react-dom";
import shuffle from "../utils/shuffle";
const shuffledArray = shuffle(array.slice());
// The below should still be able to work with graphql fetched data
// as I think the array will be saved to a variable for use in the client,
// although in my case I haven't used it so can't be fully sure
const ShuffledJSXElements = () =>
shuffledArray.map(creator => (
<li key={creator.id}>
<Link to={link}>
{creator.name}
</Link>
<img src={image} />
</li>
));
const Page = () => {
const shuffledContentContainerRef = useRef();
useEffect(() => {
const ontainer = portfolioContainerRef.current;
render(<ShuffledJSXElements />, container);
}, []);
return (
<MainWrapper>
<StyledPortfolioGridWrapper ref={shuffledContentContainerRef} />
</MainWrapper>
);
};
export default Portfolio;一个令人沮丧的事情是,容器元素在呈现内容之前不会知道自己的高度,所以布局可能会稍微跳一下。解决此问题的方法是使用min-height css属性。
https://stackoverflow.com/questions/52959147
复制相似问题