我对gatsby develop
和gatsby build
生成的站点之间的行为不一致有问题。结果是一个可以在开发中工作但不能在生产中工作的站点。
一个简单的类似博客的网站(个人资料而不是博客文章)。指标 页面是一个人的列表,列表中的每个项目都链接到该人的个人资料页面。
我正在使用Gatsby构建网站。我的数据(个人资料)是托管在Contentless无头CMS上的条目。我正在使用gatsby-source-contentful源插件。
我无法在索引页面上随机显示配置文件列表项的顺序。我的网站超越任何基本的gatsby教程的唯一行为是,我希望随机分配索引页面上的配置文件列表(以使每个人都有机会被列在顶部)。
gatsby build
生成一个静态索引页面,该列表具有一个排列的列表。
当加载到浏览器中时,ThumbList
组件会将这些项目重新改组为渲染上的另一个排列,并且某些子元素无法通过react适当地管理,并随着其他元素的移动而停留在原处。例如,这会导致配置文件图像与错误的名称配对。
为便于阅读,以下代码做了一些总结。
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 / thumbList.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
或网站的部署版本)查看索引页时,实时反应ThumbList
组件会再次在其render方法中重新整理数据。
结果重新呈现为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
中的Contentful API获取数据?答案 0 :(得分:0)
我最近也在为此苦苦挣扎!
我的解决方案是,一旦使用ReactDOM的render方法挂载父组件,就呈现混洗后的内容:
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属性。