【发布时间】:2021-06-06 16:06:00
【问题描述】:
我正在一个拥有图库和自定义构建灯箱的网站上工作。目前,我正在使用页面查询来查询我的数据,但是,我也在其他组件中使用它们来显示正确的图像和不断变化的状态。我更容易在 Context API 中存储状态,因为我的数据双向流动(我需要全局状态)并避免道具钻探。
我在 gatsby-ssr.js 和 gatsby-browser.js 中设置了我的 context.provider,如下所示:
const React = require("react");
const { PhotosContextProvider } = require("./src/contexts/photosContext");
exports.wrapRootElement = ({ element }) => {
return <PhotosContextProvider>{element}</PhotosContextProvider>;
};
我已按照 gatsby 官方文档将我的根组件包装到上下文提供程序中。
Gallery.js 我在这里获取我的数据并将它们设置为全局状态:
import { usePhotosContext } from "../contexts/photosContext";
const Test = ({ data }) => {
const { contextData, setContextData } = usePhotosContext();
useEffect(() => {
setContextData(data);
}, [data]);
return (
<div>
<h1>hey from test site</h1>
{contextData.allStrapiCategory.allCategories.map((item) => (
<p>{item.name}</p>
))}
<OtherNestedComponents />
</div>
);
};
export const getData = graphql`
query TestQuery {
allStrapiCategory(sort: { fields: name }) {
allCategories: nodes {
name
}
}
}
`;
export default Test;
注意:为了简单起见,这只是一个测试查询
我已经仔细检查了我是否获得了数据和拼写错误,并且一切正常,但是当我尝试将它们呈现出来时就会出现问题。我得到未定义的类型错误。我认为这是因为 setState 需要一些时间,所以在我第一次渲染时,contextData 数组为空,设置状态后组件可以渲染。
你知道如何解决这个问题还是我错过了什么?我应该使用不同类型的查询吗?我正在查询所有照片,所以我不需要设置任何变量。
编辑:我找到了一种解决方案,基本上我检查数据是否存在并有条件地渲染我的组件。
return testData.length === 0 ? (
<div className="hidden">
<h2>Hey from test</h2>
<p>Nothing to render</p>
</div>
) : (
<div>
<h2>Hey from test</h2>
{testData.allStrapiCategory.allCategories.map((item) => (
<p>{item.name}</p>
))}
</div>
);
但是,我发现这很老套,而且有点重复,因为我必须在我使用该数据的每个组件中使用它。所以我还在寻找其他解决方案。
【问题讨论】:
标签: javascript reactjs asynchronous graphql gatsby