gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.26k stars 10.3k forks source link

How do you customize the array map to render a limited number of images? Gatsby v2 #8974

Closed MirelesCloud closed 6 years ago

MirelesCloud commented 6 years ago

Summary

I'm still new to gatsby/react but was able to make the image gallery below work. However, I'm trying to figure out how to render only certain images from the src/images folder. Some of the images are used for other content (i.e. header image etc.) I thought by creating src/images/subfolder and moving the images I didn't want to be part of the gallery to the subfolder would solve this, but that hasn't worked. Alternatively, I've been attempting to create some sort of for-loop to limit the number of images being rendered, but haven't had any luck with that yet.

Relevant information

import React from 'react'
 import { graphql } from 'gatsby'

const IndexPage = ({data}) => (
  <div>
    <div className="main-container mb-5">
      <Gallery images={data.allImageSharp.edges}/>
    </div>
  </div>
)

export default IndexPage

export const pageQuery = graphql`
  query imageQuery {
    allImageSharp {
      edges {
        node {
          fluid(maxWidth: 600) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  }
`    

 import React from 'react'
 import Img from 'gatsby-image'

class Gallery extends React.Component {    
  render() {
    const { images } = this.props
    return (
      <div className="container-fluid bg-light standard-border">
        <div className="row">
          {images.map((img, idx) => (
            <div className="col-lg-3 col-md-4 col-xs-6" key={img.node.fluid.src}>
             <div  className="d-block mb-4 h-100 gallery">
                <Img fluid={img.node.fluid}/>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }
}

export default Gallery

Environment (if relevant)

Gatsby v2

System: OS: macOS High Sierra 10.13.6 CPU: x64 Intel(R) Core(TM) i5-4690 CPU @ 3.50GHz Shell: 3.2.57 - /bin/bash Binaries: Node: 10.11.0 - /usr/local/opt/node@10/bin/node Yarn: 1.10.1 - /usr/local/bin/yarn npm: 6.4.1 - /usr/local/bin/npm Browsers: Chrome: 69.0.3497.100 Firefox: 61.0.1 Safari: 12.0 npmPackages: gatsby: ^2.0.0 => 2.0.0 gatsby-image: ^2.0.9 => 2.0.9 gatsby-plugin-google-fonts: 0.0.4 => 0.0.4 gatsby-plugin-manifest: ^2.0.4 => 2.0.4 gatsby-plugin-react-helmet: ^3.0.0 => 3.0.0 gatsby-plugin-sharp: ^2.0.6 => 2.0.6 gatsby-plugin-typography: ^2.2.0 => 2.2.0 gatsby-source-filesystem: ^2.0.1 => 2.0.1 gatsby-transformer-remark: ^2.1.3 => 2.1.3 gatsby-transformer-sharp: ^2.1.2 => 2.1.2 npmGlobalPackages: gatsby-cli: 1.1.58

File contents (if changed)

gatsby-config.js: N/A package.json: N/A gatsby-node.js: N/A gatsby-browser.js: N/A gatsby-ssr.js: N/A

eivindflobak commented 6 years ago

Hi

You can do several queries at once and name them. For each query you specify a filter with absolutePath where you use regex to choose the correct folder.

I've edited your index.js:

import React from 'react'
import { graphql } from 'gatsby'
import Gallery from '../components/gallery'

const IndexPage = ({data}) => (

  <div>
      <Gallery images={data.cutecats.edges}/>
  </div>

)

export default IndexPage

export const pageQuery = graphql`
  query imageQuery {
    cutecats: allFile(
      filter: { absolutePath: {regex : "\/cutecats/"} }
    ) {
      edges {
        node {
          childImageSharp {
            fluid(maxWidth: 600) {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
      funnydogs: allFile(
      filter: { absolutePath: {regex : "\/funnydogs/"} }
    ) {
      edges {
        node {
          childImageSharp {
            fluid(maxWidth: 600) {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
  }
`    

Now you can access these images by using data.cutecats.edges on the line in IndexPage where you pass the GraphQL results to your Gallery component.

In the Gallery component I have done the following:

 import React from 'react'
 import Img from 'gatsby-image'

class Gallery extends React.Component {    
  render() {
    const { images } = this.props
    return (
      <div>
          {images.map((img, idx) => (

                <Img fluid={img.node.childImageSharp.fluid}/>

          ))}
      </div>
    );
  }
}

export default Gallery

This will result in an array of nodes only from the folder "cutecats".

This is how I've structured the folders and configured it in gatsby-config:

module.exports = {
  plugins: [
  `gatsby-transformer-sharp`,
  `gatsby-plugin-sharp`,

    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `cutecats`,
        path: `${__dirname}/src/images/cutecats`,
      },
    },

    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `funnydogs`,
        path: `${__dirname}/src/images/funnydogs`,
      },
    },

  ],
};

From one beginner to another.. good luck with React and GatsbyJS! 👍

MirelesCloud commented 6 years ago

@eivindflobak thank you for this. It worked like a charm. I did get a warning for not having a "key" prop, but the project still built. I'll figure out how to get rid of that. Again, thanks for your help.