使用 Isotope.js 和 React 来创建带过滤器的砌体布局?

Using Isotope.js with React to create a masonry layout with filters?

我正在使用 Gatsby 构建一个博客,我正在尝试实现一个带有过滤器的砖石网格来显示我的帖子。过去,我是通过使用 Isotope.js 来做到这一点的,所以我又使用了它。但是,它并没有真正起作用。我对 React 还是很陌生,所以我不知道哪里出了问题。

我收到此错误:TypeError: Cannot read property 'map' of undefined

import React from 'react';
import Img from 'gatsby-image';
import { Link, StaticQuery } from 'gatsby';
import Isotope from "isotope-layout/js/isotope";
import PropTypes from 'prop-types';

class FilterGrid extends React.Component {
  constructor(props) {
    super(props);
    this.onFilterChange = this.onFilterChange.bind(this);
  }

  // Click Function
  onFilterChange = (newFilter) => {
    if (this.iso === undefined) {
      this.iso = new Isotope('#grid-container', {
        itemSelector: '.grid-item',
        layoutMode: "fitRows",
        percentPosition: true,
        fitRows: {
          gutter: '.gutter-sizer'
        }
      });
    }
    if(newFilter === '*') {
      this.iso.arrange({ filter: `*` });
    } else {
      this.iso.arrange({ filter: `.${newFilter}` });
    }
  }

  render() {
    const posts = this.props.data.allMarkdownRemark.node

    return(
      // Filter Buttons
      <section className="section">
        <div className="button-group filter-button-group grid-filters">
          <div className="tabs is-centered is-toggle">
            <ul id="portfolio-flters">
              <li data-filter="*" onClick={() => {this.onFilterChange("*")}}>All</li>
              <li data-filter="brandy" onClick={() => {this.onFilterChange("brandy")}}>Brandy</li>
              <li data-filter="cachaça" onClick={() => {this.onFilterChange("cachaça")}}>Cachaça</li>
              <li data-filter="gin" onClick={() => {this.onFilterChange("gin")}}>Gin</li>
              <li data-filter="mexcal" onClick={() => {this.onFilterChange("mezcal")}}>Mezcal</li>
              <li data-filter="rum" onClick={() => {this.onFilterChange("rum")}}>Rum</li>
              <li data-filter="tequila" onClick={() => {this.onFilterChange("tequila")}}>Tequila</li>
              <li data-filter="whiskey" onClick={() => {this.onFilterChange("whiskey")}}>Whiskey</li>
              <li data-filter="vodka" onClick={() => {this.onFilterChange("vodka")}}>Vodka</li>
            </ul>
          </div>
        </div>

      <div className="grid" id="grid-container">
        <div className="grid-sizer"></div>
        <div className="gutter-sizer"></div>
        {posts.map(post => (
          <div className="grid-item {post.frontmatter.category}">
              <Link to={post.fields.slug}>
                  <figure className="image">
                      <Img fluid={post.frontmatter.image.childImageSharp.fluid} />
                      <figcaption>
                          <h4 className="title is-4">{post.frontmatter.title}</h4>
                      <p className="grid-item-blurb">{post.frontmatter.description}</p>
                      </figcaption>
                  </figure>
              </Link>
          </div>
        ))}
      </div>
    </section>
    )
  }
}

FilterGrid.propTypes = {
  data: PropTypes.shape({
    allMarkdownRemark: PropTypes.shape({
      edges: PropTypes.array,
    }),
  }),
}

export default () => (
  <StaticQuery
    query = {graphql`
      query FilterGridQuery {
        allMarkdownRemark (
          sort: { fields: [frontmatter___date], order: DESC}
          filter: { frontmatter: {templateKey: {eq: "recipe"}}}
          ) {
        edges{
          node{
            id
            frontmatter {
               title
               date
               description
               image {
                 childImageSharp {
                   resize(width: 1500, height: 1500) {
                     src
                   }
                   fluid(maxWidth: 786) {
                     ...GatsbyImageSharpFluid
                   }
                 }
               }
            }
            fields {
              slug
            }
          }
        }
      }
    }
  `}
  render={(data, count) => <FilterGrid data={data} count={count} />}
  />

)

我只是想使用 Isotope.js 因为我以前用过它,但如果有更好的方法,请告诉我!这让我发疯!

提前致谢!

在这一行

const posts = this.props.data.allMarkdownRemark.node

您不是要 allMarkdownRemark.edges 吗? allMarkdownRemark.node 绝对是未定义的。