Gatsby目前是否可以构建具有自己的graphql查询的可重用组件?如果没有,目前最少的是什么?#34;耦合"将数据传递给可重用组件的方法?我似乎找不到任何这样做的例子,我在文档中找不到任何内容。
比如说,你想为一个博客制作一个标签云组件,这个组件会显示在所有&#34; post&#34;的旁边栏中。页面以及单个&#34; / tag-cloud&#34;页。您可以使用<TagCloud limit={20} />
或<TagCloud tags={uniqueTags} />
。为此,您需要查询所有边,将每个tags
数组map-reduce / extract下拉为唯一的,有序的唯一标记字符串集。
或者,说你想要一个&#34;其他产品&#34;排除当前产品的目录页面的组件。在这里,您可能有<ProductsList exclude={currentProduct} />
。这将是构建时的直接过滤查询。
我能看到这样做的唯一方法是对来自createPages()
的查询结果进行修补,或者通过context
中的createPage({path, component, context})
传递数据。这应该发生在gatsby-node.js
吗?还有其他方法吗?
答案 0 :(得分:3)
我正在回答我自己的问题。如果有人有更好的解决方案,请提交,我很乐意接受。
我当前的解决方案,我在我的问题中引用并且我认为不是最理想的,是在pages/index.js
(或您使用createPage({path, component, context})
的任何地方构建顶级可重用组件所需的所有数据,将数据注入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;
答案 1 :(得分:3)
您可以在layouts / index.js
中创建片段查询export const avatarsFragmentQuery = graphql`
fragment avatars on RootQueryType {
avatars: allImageSharp {
edges {
node {
id
}
}
}
}
`
并在您的网页中使用它:
export const pageQuery = graphql`
query BlogQuery {
site {
siteMetadata {
title
}
}
...avatars
}
`