如何使用 reactjs 和 graphql 在 gatsby 中映射嵌套数组
Posted
技术标签:
【中文标题】如何使用 reactjs 和 graphql 在 gatsby 中映射嵌套数组【英文标题】:How to map nested array in gatsby with reactjs and graphql 【发布时间】:2020-01-16 07:48:42 【问题描述】:我有一个组件 menu.js,我将其导入页面以生成可以按类别过滤的文章列表。这完美无缺。
现在我想更改组件,以便我可以按标签过滤文章。问题是标签是 graphql 中的嵌套数组,我无法使用映射类别的相同 map() 函数来访问它。
我试图做一个嵌套的地图功能,但我不能让它工作,但我怀疑这是解决方案。我的目标是拥有相同的功能,我可以按标签而不是按类别过滤文章。我希望那是可能的。我正在使用带有 Strapi 后端的 gatsby。任何正确方向的提示表示赞赏:-)
/src/pages/articles.js
import graphql from 'gatsby'
import React from 'react'
import Layout from 'components/layout'
import MenuBlog from 'components/menublog'
const BlogPage = ( data ) => (
<Layout>
<MenuBlog items=data.menu />
</Layout>
)
export default BlogPage
export const pageQuery = graphql`
query BlogQuery
menu: allStrapiArticle
edges
node
id
title
slug
tag
title
id
category
title
id
`
这是我从上面的 GraphQL 查询中得到的,每篇文章当然可以有一个或多个标签,但只能分配一个类别
"data":
"menu":
"edges": [
"node":
"title": "articleName 1",
"slug": "articleName-1",
"category":
"title": "cat1"
,
"tag": [
"title": "tag1"
,
"title": "tag2"
,
"title": "tag3"
]
,
"node":
"title": "articleName 2",
"slug": "articleName-2",
"category":
"title": "cat2"
,
"tag": [
"title": "tag3"
]
]
这是我的组件,根据所选类别显示文章
/src/components/menublog/index.js
import React, Component from 'react'
import Link from 'gatsby'
import Row from 'react-bootstrap/Row'
const getCategories = items =>
let tempItems = items.map(items =>
return items.node.category.title
)
let tempCategories = new Set(tempItems)
let categories = Array.from(tempCategories)
categories = ['all', ...categories]
return categories
export default class MenuBlog extends Component
constructor(props)
super(props)
this.state =
items: props.items.edges,
articles: props.items.edges,
categories: getCategories(props.items.edges),
handleItems = category =>
let tempItems = [...this.state.items]
if (category === 'all')
this.setState(() =>
return articles: tempItems
)
else
let items = tempItems.filter(
( node ) => node.category.title === category
)
this.setState(() =>
return articles: items
)
render()
if (this.state.items.length > 0)
return (
<Row>
/* items */
<div className="col-md-8 blog-main bg-light">
<h1>Artikler</h1>
this.state.articles.map(( node ) =>
return (
<div key=node.id className="blog-post mb-4">
<h2>
<Link to=`/artikler/$node.slug`>node.title</Link>
</h2>
/* item text */
</div>
)
)
</div>
/* categories */
<div className="col-md-4 blog-sidebar">
<div className="p-4 mb-3 bg-light">
<h4>Kategorier</h4>
<ol className="list-unstyled mb-0">
this.state.categories.map((category, index) =>
return (
<li key=index>
<button
type="button"
className="btn"
onClick=() =>
this.handleItems(category)
>
category
</button>
</li>
)
)
</ol>
</div>
<div className="p-4 mb-3 bg-light">
<h4>Kategorier</h4>
</div>
</div>
</Row>
)
else
return <h1>no items</h1>
【问题讨论】:
【参考方案1】:您应该能够使用类似于您的类别方法的东西:
items = tempItems.filter(( node ) =>
node.tag.map(tag => tag.title).includes("tag2")
);
由于这不一定是 React / Gatsby 特定的,这里只有数据和这些方法:
const data =
data:
menu:
edges: [
node:
title: "articleName 1",
slug: "articleName-1",
category:
title: "cat1"
,
tag: [
title: "tag1"
,
title: "tag2"
,
title: "tag3"
]
,
node:
title: "articleName 2",
slug: "articleName-2",
category:
title: "cat2"
,
tag: [
title: "tag3"
]
]
;
let items = data.data.menu.edges.filter(
(
node
) => node.category.title === "cat2"
);
console.log(items);
items = data.data.menu.edges.filter((
node
) =>
node.tag.map(tag => tag.title).includes("tag2")
);
console.log(items);
【讨论】:
以上是关于如何使用 reactjs 和 graphql 在 gatsby 中映射嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章
如何在 apollo graphql reactjs 中使用 detalization 查询?
在 reactJS 中使用动态字段的 Apollo 客户端 graphql 查询