Image change using setInterval in React/Gatsby with Graphql and Gatsby Image

431 Views Asked by At

I'm trying to create an Image changing component in Gatsby/React from the results on a Graphql query. I am stuck and don't know what to do inside that setInterval function. Any Help appreciated. Thanks

import React, { useState, useEffect } from "react";
import { graphql, useStaticQuery } from "gatsby";
import Img from "gatsby-image";

function ImgRotator() {
   const imageData = useStaticQuery(graphql`
      query {
         allFile(filter: { extension: { regex: "/(jpg)|(jpeg)|(png)/" }, relativeDirectory: { eq: "rotator" } }) {
            edges {
               node {
                  id
                  childImageSharp {
                     fluid(maxWidth: 2880) {
                        ...GatsbyImageSharpFluid_withWebp
                     }
                  }
               }
            }
         }
      }
   `);

   const allImages = imageData.allFile.edges;
   const [images] = useState(allImages);
   const [displayImage, setDisplayImage] = useState(imageData.allFile.edges[0].node.childImageSharp.fluid);


   useEffect(() => {
      const interval = setInterval(() => {

         // Help! Don't know what to do here

      }, 1000);
      return () => clearInterval(interval);
   }, [displayImage]);

   return <Img fluid={displayImage} alt="" loading="eager" />;
}

export default ImgRotator; 
 
1

There are 1 best solutions below

2
On

One workaround that may work for you is:

    import React, { useState, useEffect } from "react";
    import { graphql, useStaticQuery } from "gatsby";
    import Img from "gatsby-image";
    
    function ImgRotator() {
       const imageData = useStaticQuery(graphql`
          query {
             allFile(filter: { extension: { regex: "/(jpg)|(jpeg)|(png)/" }, relativeDirectory: { eq: "rotator" } }) {
                edges {
                   node {
                      id
                      childImageSharp {
                         fluid(maxWidth: 2880) {
                            ...GatsbyImageSharpFluid_withWebp
                         }
                      }
                   }
                }
             }
          }
       `);
    
       const allImages = imageData.allFile.edges;
       const [currentImage, setCurrentImage]=useState({});
       const [currentIndex, setCurrentIndex]=useState(0);
    
    
       useEffect(() => {
          const interval = setInterval(() => {
                 
            setCurrentImage(allImages[currentIndex].node.childImageSharp.fluid)
             setCurrentIndex(currentIndex++)
                  
          }, 1000);
          return () => clearInterval(interval);
       }, [currentIndex]);
    
       return <Img fluid={currentImage} alt="" loading="eager" />;
    }
    
    export default ImgRotator; 

Summarizing, you initially set two states:

   const [currentImage, setCurrentImage]=useState({});
   const [currentIndex, setCurrentIndex]=useState(0);

Quite self-explanatory: currentImage will store your displayed image and currentIndex the index in the array of that image.

In your useEffect (triggered once the currentIndex changes) you've defined an interval where it looks for the currentIndex in allImages and sets the currentImage using that index. Each second the function is being triggered again so it will update the system.

Your gatsby-image will show the currentImage based on that interval:

   return <Img fluid={currentImage} alt="" loading="eager" />;