我当前的 GatsbyJS 项目是一个带有轮播和其他内容的单页寻呼机。
背景
转盘上应装有有关某些产品的信息。我的目标是让轮播通过遍历所有markdown文件来构建自身,并在文件顶部选择以下三行的文件:
---
type: product
---
因此,我创建了一个CarouselContainer
(类组件)和一个Carousel
组件(功能组件)。容器应通过GraphQL查询加载markdown并将结果产品对象传递给其嵌套组件。然后,组件应在对象上映射并创建轮播。
但是,还有其他用于菜单列表,文本模式等的markdown文件。他们有type: page
。我认为准备一些GraphQL查询将是解决方案。但这比预期的要困难得多...
容器组件是一个类组件,因此无法直接在其中调用查询(https://github.com/gatsbyjs/gatsby/issues/3991#issuecomment-364939030)。
然后我认为将多个查询放入pages/index.js
可能是解决方案。
export const indexQuery = graphql`
query IndexQuery {
allMarkdownRemark(filter: {frontmatter: {type: {eq: "page"}}}) {
edges {
node {
frontmatter {
title
text
}
}
}
}
}
`
export const productsQuery = graphql`
query ProductsQuery {
allMarkdownRemark(filter: {frontmatter: {type: {eq: "product"}}}) {
edges {
node {
id
frontmatter {
title
content
}
}
}
}
}
`
不再。使用GraphQL片段应该是一个解决方案...
Q 有人可以告诉我如何为此目的准备片段吗?和/或还有另一个想法如何将降价内容正确地放入我的容器中?
感谢阅读。
答案 0 :(得分:2)
距离您不太远。 GraphQL支持在同一查询中查询多个离散节点:
export const query = graphql`
{
products: allMarkdownRemark(
filter: { frontmatter: { type: { eq: "product" } } }
) {
edges {
# ...
}
}
pages: allMarkdownRemark(
filter: { frontmatter: { type: { eq: "pages" } } }
) {
edges {
# ...
}
}
}
`
请注意,我已经使用别名在同一GraphQL查询中使用单独的过滤器来获取同一初始节点(allMarkdownRemark
)。这将导致data.products
和data.pages
被传递到您的default
导出的React组件中。
要清理此问题,可以使用片段,使您可以在products
文件中并置Carousel
查询:
在carousel.js
中(或任何包含您的Carousel组件的文件中):
export const query = graphql`
fragment Products on Query {
products: allMarkdownRemark(
filter: { frontmatter: { type: { eq: "product" } } }
) {
edges {
# ...
}
}
}
`
然后在您的页面文件中:
export const query = graphql`
{
pages: allMarkdownRemark(
filter: { frontmatter: { type: { eq: "pages" } } }
) {
edges {
# ...
}
}
...Products
}
`
注意:如果您使用的是Gatsby 1.x,则需要将片段的on Query
部分更改为on RootQueryType
。
假设您正在使用Gatsby v2,则也可以使用StaticQuery而不是将查询合并为一个查询。如果您的网页与产品的轮播无关,那么此功能特别有用。
import React from "react";
import { graphql, StaticQuery } from "gatsby";
class Carousel extends React.Component {
// ...
}
export default props => (
<StaticQuery
query={graphql`
products: allMarkdownRemark(
filter: { frontmatter: { type: { eq: "product" } } }
) {
edges {
# ...
}
}
`}
render={({ products }) => <Carousel products={products} {...props} />}
/>
);