Search code examples
javascriptreactjstypescriptslidercarousel

Slider to go to the end from index[0] React Typescript project


I am working on a personal project using React.js and Typescript. I build a slider that works fine so far, but there is one issue. When the slider is in the position 1, thus index[0], and the user press the "back" button to go back one more slide, I would like the slider to go to the end.

This is the code:

import { useEffect, useRef, useState } from "react";
import "./styles.css";

const colors: string[] = ["#0088FE", "#00C49F", "#FFBB28"];

export default function App() {
  const [activeIndex, setActiveIndex] = useState<number>(0);
  const timeOutRef = useRef<null | number>(null);

  const delay: number = 2500;

  const resetTimeOut = () => {
    if (timeOutRef.current) {
      clearTimeout(timeOutRef.current);
    }
  };

  const handleArrowRight = () => {
    if (activeIndex === colors.length - 1) {
      setActiveIndex(0);
    } else setActiveIndex(activeIndex + 1);
  };

  const handleArrowLeft = () => {
    if (activeIndex === 0) return;
    setActiveIndex(activeIndex - 1);
  };

  useEffect(() => {
    resetTimeOut();
    timeOutRef.current = setTimeout(
      () =>
        setActiveIndex((prevIndex: number) =>
          prevIndex === colors.length - 1 ? 0 : prevIndex + 1
        ),
      delay
    );
    return () => {
      resetTimeOut();
    };
  }, [activeIndex]);

  return (
    <div className="App">
      <div className="slideVisible">
        <div
          className="slideContainer"
          style={{ transform: `translate3d(${-activeIndex * 100}%, 0, 0)` }}
        >
          {colors.map((colored, index) => (
            <div
              key={index}
              className="slide"
              style={{ backgroundColor: colored }}
            ></div>
          ))}
        </div>
        <button onClick={handleArrowLeft} className="leftArrow">
          Back
        </button>
        <button onClick={handleArrowRight} className="rightArrow">
          Next
        </button>
        <div className="slideDotsContainer">
          {colors.map((_, index) => (
            <div
              key={index}
              className={`slideDots ${activeIndex === index ? "active" : ""}`}
              onClick={() => setActiveIndex(index)}
            ></div>
          ))}
        </div>
      </div>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

Also, this is a CodeSandBox link with the css on it


Solution

  • Notice how you're just returning in handleArrowLeft if activeIndex === 0. You can change that to go to last index instead of just return. Like this:

      const handleArrowLeft = () => {
        if (activeIndex === 0) {
          setActiveIndex(colors.length - 1)
        } else {
          setActiveIndex(activeIndex - 1);
        }
      };
    

    forked working sandbox