0

i'm trying to change img src on hover, so i decided to change src through state by looping through the sourecs array onMouseenter but every time i get the last element only. i read some articles and i knew that i cant't use useState inside a loop, but i can't find another way to do it. you can take a look at my code bellow

import React, { useEffect, useState } from "react";
import { Col } from "react-bootstrap";
import { Link } from "react-router-dom";
import "./productListItem.css";
const ProductListItem = ({}) => {
  const imgSrc = [
    "/img/products_carousel/Untitleddesign_40_460x.webp",
    "/img/products_carousel/Untitleddesign_30_460x.webp",
    "/img/products_carousel/SkinRejuvenation_460x.webp",
  ];
  const [currentImg, setCurrentImage] = useState(imgSrc[0]);

  const changeImageSrc = () => {
    imgSrc.forEach((element) => {
      setInterval(() => {
        setCurrentImage(element);
      }, 1000);
    });
  };

  const handleMouseLeave = () => {
    setCurrentImage(imgSrc[0]);
  };

  return (
    <Col
      sm={4}
      onMouseEnter={() => changeImageSrc()}
      onMouseLeave={() => handleMouseLeave()}
    >
      {console.log({ currentImg })}
      <Link to="/" className="list-collections__item">
        <div class="list-collections__item-image-wrapper image-zoom">
          <img
            class="list-collections__item-image"
            loading="lazy"
            sizes="(max-width: 740px) calc(100vw - 48px), (max-width: 999px) calc(50vw - 60px), 480px"
            height="380"
            width="380"
            alt=""
            src={currentImg}
          />
        </div>
        <div className="list-collections__item-label mt-2">
          <div>Queen</div>
          <div>LE 2,500.00</div>
          {/* </>
          )} */}
        </div>
      </Link>
    </Col>
  );
};

export default ProductListItem;
mostafa elbanna
  • 195
  • 2
  • 3
  • 9
  • 1
    This sets up an interval for every single element. You want an interval that increments through the elements (e.g., a counter). – Dave Newton Aug 05 '22 at 16:16
  • Are you trying to say at 1 second show img[0] then at 2 seconds show img[1] then at 3 seconds show img[2]? what is the main objective you are trying to do? – Colin Hale Aug 05 '22 at 16:25
  • what exactly do you want to do here? – DecPK Aug 05 '22 at 16:25
  • Could you explain to us what is exatcly that you are trying to do with your code? I dit not understand the main reason behind the setInterval – Pedro Borges Jr Aug 05 '22 at 16:30
  • @ColinHale exactly i want to make slider that start when i hover on the image – mostafa elbanna Aug 05 '22 at 17:33
  • @mostafaelbanna The answer I gave should do want you want then, just need to update it so it fits your needs – Colin Hale Aug 05 '22 at 17:38
  • @ColinHale I tried your solution it works , but have some issue sometimes , it start to run before i hover and also it stop when the loop hit the last element i wanted it to be infinite till mouseleave – mostafa elbanna Aug 05 '22 at 18:56
  • @PedroBorgesJr i'm trying to make slider that change image on hover every second, so i'm trying to do it by using state to change image src – mostafa elbanna Aug 05 '22 at 19:19
  • @NullPointerException i'm trying to make slider that change image on hover every second, so i'm trying to do it by using state to change image src – mostafa elbanna Aug 05 '22 at 19:20

1 Answers1

1

I am a little lost on the main objective, but trying to interpret from your code, if you are trying to start an animation sequence to show each image 1 second apart you could use recursion to start the sequence then have the function call itself as long as there are more elements in the array. Here is an example:

export default function App() {
  const [text, setText] = useState("Default image");
  const arr = ["Image of cat", "Image of dog", "Image of lizard"];

  const startHoverEvents = (i, a) => {
    setTimeout(() => {
      setText(a[i]);
      if (i < a.length - 1) {
        startHoverEvents(i + 1, a);
      }
    }, 1000);
  };

  return (
    <div className="App" onMouseEnter={() => startHoverEvents(0, arr)}>
      <h1>{text}</h1>
    </div>
  );
}
Colin Hale
  • 824
  • 5
  • 11