Search code examples
reactjsgatsbygatsby-image

Best way to change image on hover using GatsbyImage


I do want my product images to change during mouse hover, but since GatsbyImage doesn't support onMouseEnter props, what is the best way to handle this?

The ProductImage:

<GatsbyImage
              alt={firstImage?.altText ?? title}
              image={firstImage?.gatsbyImageData ?? storefrontImageData}
              loading={eager ? "eager" : "lazy"}
              className="object-cover object-center w-full h-full group-hover:opacity-75"
            />
          </div>

Where firstImage is the first object in the array, and secondImage will be the second image/object inside the images array, pulled from Shopify, which needs to be the active image when hovering.

I was thinking about a solution to make two divs with in each of one an unique image, and just activate and animate the second div using Framer Motion when hovering (using conditional rendering). But as far as I am concerned, this is not a clean way to do it.. I want to follow best practices but I am still learning a lot, so this is why I am asking for some help :)


Solution

  • You can just create a wrapper div that listens to onMouseEnter/onMouseLeave events:

    const [activeImage, setActiveImage]= useState("gatsby");
    // ...
    
      <div onMouseEnter={setActiveImage("store")} onMouseLeave={setActiveImage("gatsby")}>
          {activeImage === "gatsby" ? <GatsbyImage
                      alt={firstImage?.altText ?? title}
                      image={firstImage?.gatsbyImageData}
                      loading={eager ? "eager" : "lazy"}
                      className="object-cover object-center w-full h-full group-hover:opacity-75"
                    /> : <GatsbyImage
                      alt={"Second Image"}
                      image={storefrontImageData}
                      loading={eager ? "eager" : "lazy"}
                      className="object-cover object-center w-full h-full group-hover:opacity-75"
                    />}
        </div>
    

    Your setActiveImage can be whatever you need, in this case, I've set a function that changes between gatsby and store to presentation purpose but can be a boolean, etc.