Reactjs unexpected useState behaviour in slider

I implemented autoplay Slider (having three cards) using useEffect, but manual "previous" and "forward" button are not working properly. useState is not upadating values as desired. useState is changing values that i am unable to understand that random behaviour. Once i clicked on previous or forward arrow to swipe slide than it started changing slides very quickly. Auto slider is working perfectly but i swipe manually than usestate changes value unexpectedly. how can i implement both auto and manual (forward and backward arrow) so that usestate changes value smoothly.

import React, { useState, useRef, useEffect } from "react";
import { Card, Grid } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import { SlideData, SliderImages } from "./SlideData";
import left from "../../../styles/img/homepg/AdmSlider/left.png";
import right from "../../../styles/img/homepg/AdmSlider/right.png";


function NewsSlider() {
  const classes = useStyles();

  const firstRef = useRef(null);
  const secondRef = useRef(null);
  const thirdRef = useRef(null);
  const currentRef = useRef(null);


  const Left = () => {
    setFirst(first <= 0 ? len : first - 1);
    setSecond(second <= 0 ? len : second - 1);
    setThird(third <= 0 ? len : third - 1);
  };

  const Right = () => {
    setFirst(first >= len ? 0 : first + 1);
    setSecond(second >= len ? 0 : second + 1);
    setThird(third >= len ? 0 : third + 1);
  };

  const [first, setFirst] = useState(0);
  const [second, setSecond] = useState(1);
  const [third, setThird] = useState(2);

  const length = SliderImages.length;
  const len = length - 1;
  let timeout;
  
  useEffect(() => {
    setTimeout(() => {
      setFirst(first >= len ? 0 : first + 1);
      setSecond(second >= len ? 0 : second + 1);
      setThird(third >= len ? 0 : third + 1);
       return () => clearTimeout(timeout);
    }, 3000);
  }, [first, second, third]);

  return (
    <>
      <div>
        <Grid container xs={12} className={classes.grid}>
          {" "}
          <div>
            <img
              src={left}
              alt="leftarrow"
              className={classes.left}
              onClick={Left}
            />
          </div>
          <Grid item xs={4} className={classes.card}>
            {SliderImages.map((val, index) => {
              return (
                <div>
                  {index === first && (
                    <Card className={classes.card1}>
                      <img
                        src={val.imgsrc}
                        alt={val.title}
                        className={classes.image}
                        ref={firstRef}
                      />
                    </Card>
                  )}
                  {index === second && (
                    <Card className={classes.card2}>
                      <img
                        src={val.imgsrc}
                        alt={val.title}
                        className={classes.image}
                        ref={secondRef}
                      />
                    </Card>
                  )}
                  {index === third && (
                    <Card className={classes.card3}>
                      <img
                        src={val.imgsrc}
                        alt={val.title}
                        className={classes.image}
                        ref={thirdRef}
                      />
                    </Card>
                  )}
                  <div>
                    <img
                      src={right}
                      alt="rightarrow"
                      className={classes.right}
                      onClick={Right}
                    />
                  </div>
                </div>
              );
            })}
          </Grid>
        </Grid>
      </div>
    </>
  );
}

export default NewsSlider;

13 thoughts on “Reactjs unexpected useState behaviour in slider”

Leave a Comment