【问题标题】:How to get running Gatsby page query data with React Context API?如何使用 React Context API 运行 Gatsby 页面查询数据?
【发布时间】:2021-06-06 16:06:00
【问题描述】:

我正在一个拥有图库和自定义构建灯箱的网站上工作。目前,我正在使用页面查询来查询我的数据,但是,我也在其他组件中使用它们来显示正确的图像和不断变化的状态。我更容易在 Context API 中存储状态,因为我的数据双向流动(我需要全局状态)并避免道具钻探。

我在 gatsby-ssr.jsgatsby-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


    【解决方案1】:

    将 [page queried] 数据传递给 root provider [在 gatsby 和 apollo 中都没有意义] - 数据重复,并非所有页面/等都需要。

    ...此数据在构建时获取,因此无需检查长度/加载/等

    ...您可以在页面组件中渲染提供程序,以使用上下文将数据传递给子组件(无需道具钻探)。

    【讨论】:

    • 很抱歉,您可以附上代码,我的英语不是最好的,我不确定我是否理解正确。
    • 什么用例/结构/组件/页面?数据在哪里传递/使用?也不清楚
    • 我在 /pages 目录中有portfolio.js 文件,我在这里获取我的数据。在这个站点中,我渲染了一些标题、文本和我的其他组件 gallery.js。 Gallery.js 组件使用查询的数据。这里我有另一个组件 lightbox.js,它是我的自定义灯箱,该组件接收当前选定图像的 ID、所有图像(查询数据)和过滤的照片。根据gallery.js中当前选择的过滤器(照片类别),我更改过滤后的照片数组,并设置我的nextPhoto和prevPhoto。
    • 这里没有复杂性,只是将数据作为props传递...问题出在哪里?
    • 例如,我需要将来自 gallery.js 的 currentPhotoId 更新为 lightbox.js 作为道具。我正在 lightbox.js 中更新它。这就是我想使用全局状态的原因。
    猜你喜欢
    • 1970-01-01
    • 2019-04-03
    • 2019-04-26
    • 2020-12-04
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 2019-06-22
    相关资源
    最近更新 更多