javascript - 具有自己查询的 Gatsby 可重用组件

标签 javascript graphql gatsby

目前是否可以在 Gatsby 中构建具有自己的 graphql 查询的可重用组件?如果不是,目前将数据传递给可重用组件的“耦合”最少的方法是什么?我似乎找不到任何执行此操作的示例,而且我在文档中也找不到任何内容。

例如,您想要为博客创建一个标签云组件,它会显示在所有“post”页面的侧边栏以及单个“/tag-cloud”页面上。你可以像<TagCloud limit={20} />一样使用或 <TagCloud tags={uniqueTags} /> .为此,您需要查询所有边,map-reduce/提取每个 tags排列成一组唯一的、有序的唯一标记字符串。

或者,假设您想要一个排除当前产品的目录页面的“其他产品”组件。在这里,你可能有 <ProductsList exclude={currentProduct} /> .这将是构建时的直接过滤查询。

我能看到的唯一方法是对来自 createPages() 的查询结果进行猴子修补。或者通过 context 传递数据在 createPage({path, component, context}) .如果这发生在 gatsby-node.js ?还有其他方法吗?

最佳答案

我正在回答我自己的问题。如果有人有更好的解决方案,请提交,我会很乐意接受。

我在我的问题中引用了我当前的解决方案,我认为这是次优的,它是在 pages/index.js(或任何你使用 createPage({path, component, context}) 并将数据注入(inject)到 context 中。这使得 component 构造函数可以通过 pathContext 属性。名称 pathContext 让我觉得这是对这个对象精神的滥用,但它完成了工作。

例如,如果您有一个博客,其条目可能包含一组标签,这可能是您的 gatsby-node.js:

const path = require('path');

const getUniqueTags = edges => {
    const set = new Set();

    edges.forEach(edge => edge.node.frontmatter.tags.forEach(tag => set.add(tag)));

    return [...set];
};

exports.createPages = ({ graphql, boundActionCreators }) => resolve(graphql(`
        query AllPagesQuery {
            allMarkdownRemark {
                edges {
                    node {
                        frontmatter {
                            path
                            tags
                        }
                    }
                }
            }
        }
    `)))
    .then(({ errors, data }) => {
        const { createPage } = boundActionCreators;
        const pageTemplate = path.resolve('./src/templates/page.js');

        if (errors) return Promise.reject(errors);

        return data.allMarkdownRemark.edges.forEach(edge => {
            createPage({
                path: edge.node.frontmatter.path,
                component: pageTemplate,
                context: {
                    path: edge.node.frontmatter.path,
                    tags: getUniqueTags(data.allMarkdownRemark.edges)
                }
            });
        });
    })
    .catch(err => console.log(err));

然后你的 templates/page.js 可以像这样接收唯一的标签数组:

const IndexPage = ({ pathContext }) => {
    const { tags } = pathContext.map(tag => <li>{ tag }</li>);

    return <div>{ tags }</div>;
};

export default IndexPage;

关于javascript - 具有自己查询的 Gatsby 可重用组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46519893/

相关文章:

javascript - 在javascript中将字节数组转换为字符串

javascript - 使用 Apollo Graphql Server 解析关系文档

javascript - GraphQL - 动态创建查询的形状

reactjs - 将 objectFit 与来自 gatsby-plugin-image 的 StaticImage 结合使用

javascript - Gatsby - 无法读取未定义的属性 'component---src-pages-index-jsx'

reactjs - typescript 和 Gatsby : Development bundle cannot resolve paths but VS Code can

javascript - 在提交调用 webapi 之前获取 Angularjs 变量中的输入值

javascript - Angularjs promise 这个引用窗口

javascript - 对象字面量动态键

node.js - Prisma 绑定(bind)无法连接到 prisma 服务器。请求 http ://localhost:4466/failed, 原因 : connect ECONNREFUSED 127. 0.0.1:4466