javascript - 使用 Isotope.js 和 React 创建一个带过滤器的砌体布局?
问题描述
我正在用 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
绝对是未定义的。
推荐阅读
- python - 在旧版 (EOL) SNI 上安装 certbot-auto 时出现加密 403 错误是必需的错误
- java - java - 如何使Java Rest API在前半部分处理后返回响应,然后在返回响应后继续下半部分?
- php - Gitlab CI 和 php 版本
- modal-dialog - modal ionic 1 中的 appery.io 固定组件
- c++ - 一种检查 is_explicitly_constructible 的方法
- css - CSS 值更改触发的 CSS 动画
- nunit - 无法通过控制台运行我的 SpecFlow 功能代码
- css - 媒体查询的网格参数
- html - CSS Sticky 属性在此演示中不起作用
- javascript - 当我将注意力集中在下拉空格上时,不会打开我的下拉菜单