?
Мой текущий проект GatsbyJS - это одностраничный пейджер с каруселью и некоторым другим контентом.
Фон
Карусель должна быть заполнена информацией о некоторых товарах. Моя цель - позволить карусели построить себя, перебирая все файлы уценки, выбирая те, у которых есть эти три строки в верхней части файла:
---
type: product
---
Итак, я создал CarouselContainer (компонент класса) и компонент Carousel (функциональный компонент). Контейнер должен загружать уценку через запрос GraphQL и передавать полученный объект продуктов во вложенный компонент. Затем компонент должен отобразить объект и создать карусель.
Но есть также другие файлы разметки для списков меню, текстовых модальных окон и так далее. У них есть 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 Может кто-нибудь сказать мне, как подготовить фрагменты для этой цели. и / или есть другая идея, как получить содержимое разметки прямо в мой контейнер?
Спасибо за прочтение.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы не так уж и далеко. 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 в ваш экспортированный компонент React default.
Чтобы очистить это, вы можете использовать фрагменты, позволяющие разместить ваш запрос products в вашем файле Carousel:
В carousel.js (или любом другом файле, в котором находится ваш компонент карусели):
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} />}
/>
);
Для других, читающих этот вопрос: я не могу утверждать, что полностью понимаю это, но это решение сработало для меня только тогда, когда я удалил {}, окружающий products, в строке render=. В моем случае рабочий код был render = {( settings_query ) => <Interface settings = {settings_query} {...props} />}. Так что, если у вас возникли проблемы, возможно, стоит попробовать.
@RobinL Этот бит разрушает свойство product объекта props.
Спасибо, сработало! Первый способ с псевдонимами работал очень хорошо. StaticQuery - предпочтительный способ. Раньше не знал об этой функции, потому что несколько недель назад я начал с v1.