在Gatsby JS的同一页面上根据类别对文章进行分组

时间:2019-09-23 14:45:34

标签: javascript gatsby

我有一个Gatsby JS网站,我想在同一页面上显示按“家庭”(基本上是类别)分组的文章列表。

这是我到目前为止所做的:

...

{edges.map(({ node }) => {

              let families = []
              _.each(edges, edge => {
                  if (_.get(edge, "node.frontmatter.family")) {
                      families = families.concat(node.frontmatter.family)
                  }
              })

              _.forEach(family => {
                  const articlesinfamily = () => {
                      return edges.filter(edge => edge.node.frontmatter.family === family)
                  }

           return (
                  <>
                  <div className="column is-3">
                    <div className="content">
                      <div className="title is-3">
                          {family}
                      </div>
                      <p>Description</p>
                    </div>
                  </div>
                  <div className="column is-9">

                    <div className="columns is-multiline">
                      {articlesinfamily.map(({ node }) => {
                        <div className="column is-4">
                          <div className="content">
                            <div className="title is-4">
                                {node.frontmatter.name}
                            </div>
                            <p>{node.frontmatter.headline}</p>     

                           </div>
                         </div>
                      })}

                    </div>
                  </div>
                  </>   
                )
              })
          })}



...

此代码不起作用,但我认为这是我找到的最接近的解决方案。 我得到的错误是

  

期望了一个赋值或函数调用,而是看到了一个表达式

在我拥有{articlesinfamily.map(({{node})=> {....

关于如何进行这项工作的任何线索?有没有更好的方法来达到预期的效果?

非常感谢。

2 个答案:

答案 0 :(得分:2)

您在最初的问题中遇到的错误:

  

期望了一个赋值或函数调用,而是看到了一个表达式

...表示此表达式位于您的map中:

{articlesinfamily.map(({ node }) => {
  <div className="column is-4">
    <div className="content">
      <div className="title is-4">
        {node.frontmatter.name}
      </div>
      <p>{node.frontmatter.headline}</p>     
    </div>
  </div>
})}

...实际上没有被使用。您既不会将其分配给任何变量,也不会调用函数。

您在发布的答案中发现的解决方案是返回表达式(因此可以在函数中使用它):

{articlesinfamily.map(({ node }) => {
  return (
    <div className="column is-4">
      <div className="content">
        <div className="title is-4">
          {node.frontmatter.name}
        </div>
        <p>{node.frontmatter.headline}</p>     
      </div>
    </div>
  )
})}

您也可以使用更简洁的implicit return,方法是将大括号替换为括号:

{articlesinfamily.map(({ node }) => (
  <div className="column is-4">
    <div className="content">
      <div className="title is-4">
        {node.frontmatter.name}
      </div>
      <p>{node.frontmatter.headline}</p>     
    </div>
  </div>
))}

答案 1 :(得分:0)

经过进一步研究,我使用Graphql'group'来解决了这个问题,

查询页面:

export const updatesQuery = graphql`
  query {
    allMarkdownRemark( filter: {  frontmatter: { contentType: { eq: "updates" } } } ) {
      group(field: frontmatter___family) {
        fieldValue
        totalCount
        edges {
          node {
            frontmatter {
              name
              headline
              path
            }
          }
        }
      }
    }
  }
`

然后在页面组件中,我首先使用group.map(),然后使用edge.map()来捕获组中的所有“内容”。像这样:

...

        {data.allMarkdownRemark.group.map(( { fieldValue, edges } ) => {

               return (

                  <>
                  <div className="column is-3">
                    <div className="content">
                      <div className="title">
                          {fieldValue}
                      </div>
                    </div>
                  </div>
                  <div className="column is-1"></div>
                  <div className="column is-8">

                      <div className="columns is-multiline">

                          {edges.map(( { node } ) => {

                            return (

                              <div className="column is-4">
                                <div className="content">
                                    <div className="title">{node.frontmatter.name}</div>
                                    <p>{node.frontmatter.headline}</p>     

                                </div>
                              </div>

                            )    
                          })}

                    </div>
                  </div>
                  </>   
               )    
          })}

...

希望这对您也有帮助。