Mapping array of images leads to the same image repeating on every instance

这一生的挚爱 提交于 2021-02-05 11:34:50

问题


Im trying to map an object from an array of arrayed images into an image gallery on separate product pages (coming from strapi). The correct number of images appear but it repeats the same image over them. Even on product pages that shouldn't include that image in their respective array. examples - https://imgur.com/a/PKlpofy

Ive checked the source and the image src links are all different versions of the same image. - https://imgur.com/a/968w77b

GraphIQL - https://imgur.com/a/HvgMA8r

Any pointers on where im going wrong would be great! please let me know if you need any more info.

Code-

<div className="image-grid">
                {data.home.galleryImage.map((image, id, caption) => (
                    
                      <Image fluid={image.formats.medium.childImageSharp.fluid} alt="hh" key={id} class="galleryimg" thumbnail/> 
                   
                ))  
                }
                </div>
        </div>

GraphQL query -

export const query = graphql`
      query GetSingleHome($slug: String) {
        home: strapiHomes(slug: { eq: $slug }) {
        galleryImage {
          id 
          formats {
            medium {
              childImageSharp {
               fluid(maxWidth: 400, maxHeight: 250) {
                 ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
        }
      }
    `

回答1:


You are not setting properly the key value. image is the iterable object, is just a way of naming each index of your galleryImage so the id, doesn't stand as the id of the image itself.

Change it to:

<div className="image-grid">
  {data.home.galleryImage.map((image) => (
     <Image fluid={image.formats.medium.childImageSharp.fluid} alt="hh" key={image.id} class="galleryimg" thumbnail/>  
   ))}
</div>

To access the nested image properties, you need to access its child properties, like the way you do in image.formats, accessing to formats position, but using image.id.

For further details, you can check the MDN docs.

In addition, if the loop is printing the same image, internally the id is not correctly set from GraphQL when created the data node from Strapi. You can customize the GraphQL node schema to add custom parameters in order to bypass this limitation using different APIs provided by Gatsby, createRemoteFileNode should fit your requirements.

 const { createRemoteFileNode } = require(`gatsby-source-filesystem`);
    
    exports.onCreateNode = async ({ node, actions, store, cache }) => {
      const { createNode, createNodeField } = actions;
    
      if (node.internal.type !== null && node.internal.type === "StrapiPortfolio") {
        for (const category of node.category) {
          for (const image of category.images) {
            console.log(image);
            const fileNode = await createRemoteFileNode({
              url: "http://localhost:1337" + image.url,
              store,
              cache,
              createNode,
              createNodeId: (id) => image.id.toString(),
            });
    
            if (fileNode) {
              image.localFile___NODE = fileNode.id;
            }
          }
        }
      }
    };

Source: How to query multiple images in Gatsby from Strapi using Graphql

Depending on your data structure, you may need to change the loop and some other parameters. In this case, images are inside a category node so, it has to be inferred by nesting two different loops.

The idea is to loop through all your image nodes and add the localFile___NODE field with:

  image.localFile___NODE = fileNode.id;

The id is previously created in:

  createNodeId: (id) => image.id.toString(),


来源:https://stackoverflow.com/questions/65617024/mapping-array-of-images-leads-to-the-same-image-repeating-on-every-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!