javascript - How to use GraphQL queries in a container class component
问题描述
My current GatsbyJS project is a one pager with a carousel and some other content.
Background
The carousel should be filled with information about some products. My goal is to let the carousel build itself by iterating through all markdown files, picking the ones with these three lines at the top of the file:
---
type: product
---
So I've created a CarouselContainer
(class component) and a Carousel
component (functional component). The Container should load the markdown via GraphQL query and pass the resulting products object to it's nested component. Then the component should map over the object and create the carousel.
But there are also other markdown files for menu lists, text modals and so on. They have the type: page
. I thought preparing a few GraphQL queries would be the solution. But it turned out to be more difficult than expected...
The container component is a class component, so I am not able to call the query directly in it (https://github.com/gatsbyjs/gatsby/issues/3991#issuecomment-364939030).
Then I thought putting multiple queries into the pages/index.js
could be the solution.
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
}
}
}
}
}
`
Nope again. Using GraphQL fragments should be a solution...
Q Can someone tell me how to prepare fragments for that purpose and/or have another idea how to get the markdown content right into my container?
Thanks for reading.
解决方案
你离得并不远。GraphQL 支持在同一个查询中查询多个离散节点:
export const query = graphql`
{
products: allMarkdownRemark(
filter: { frontmatter: { type: { eq: "product" } } }
) {
edges {
# ...
}
}
pages: allMarkdownRemark(
filter: { frontmatter: { type: { eq: "pages" } } }
) {
edges {
# ...
}
}
}
`
请注意,我使用别名allMarkdownRemark
在同一个 GraphQL 查询中使用不同的过滤器来获取相同的初始节点 ( )。这将导致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} />}
/>
);
推荐阅读
- javascript - Node.JS 只返回 MySQL“WHERE IN”子句的部分记录
- javascript - 为什么在第一个孩子之前插入不起作用
- c# - 如何在实体框架中将多个实体合二为一(将复杂实体映射到单个表中)
- java - Spring如何存储有关2个实体之间关系的信息
- wpf - 如何在 Prism 中为我的对话窗口设置区域管理器?
- nginx - 在重定向到实际后端之前显示静态页面
- php - 仅当检查了至少一种产品变体时,如何通过 Wp Query 显示产品 - WooCommerce?
- html - 尝试使用网格系统水平组织引导卡
- sql-server - 如何在sql server中根据时间可用性返回记录
- math - 我想使用橙色数据挖掘工具定义多个目标,以使用 RSSI(接收信号强度)方法确定位置(x,y)