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

目前Gatsby中是否可以构建具有自己的graphql查询的可重用组件?如果没有,目前将数据传递给可重用组件的最小“耦合”方式是什么?我似乎无法找到任何这样做的例子,我在文档中找不到任何东西.

比如说,您想为博客创建一个标签云组件,该组件将显示在所有“发布”页面的侧栏以及单个“/ tag-cloud”页面上.您可以使用< TagCloud limit = {20} />或< TagCloud tags = {uniqueTags} />.为此,您需要查询所有边,将每个标记数组map-reduce / extract下移到唯一的,有序的唯一标记字符串集.

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

我可以看到这样做的唯一方法是从createPages()中修补查询结果,或者通过createPage({path,component,context})中的上下文传递数据.这应该发生在gatsby-node.js吗?还有其他方法吗?

解决方法:

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

我在我的问题中引用的当前解决方案,我认为不是最理想的,是构建pages / index.js中的*可重用组件所需的所有数据(或者使用createPage({path,component,context}的任何地方)并将数据注入上下文.这使得组件构造函数可以通过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;
上一篇:Graphql-Java快速入门指导


下一篇:它最强大的优势在于,你能够精确的定义所需要的数据,并且毫无冗余