react useRef in carousel

Viewed 94

I have a carousel that prints out a lists of data, 5 in total, the issue is when I click on the next of any of the carousel buttons, only the bottom carousel updates. Any suggestions? Here is my react tailwind code :

// query all available genres and for it create a listview row of the content
import { useState, useRef, useEffect } from "react";
import React from "react";
import ShowList from "./showlist.json";
import "./carousel.css";
import data from "./data.json";

export default function Genre() {
  const maxScrollWidth = useRef(0);
  const [currentIndex, setCurrentIndex] = useState(0);
  const listCarousel = useRef(0);
  const containerCarousel = useRef(0);

  const movePrev = () => {
    if (currentIndex > 0) {
      setCurrentIndex((prevState) => prevState - 1);
    }
  };

  const moveNext = () => {
    if (
        listCarousel.current !== null &&
        listCarousel.current.offsetWidth * currentIndex <= maxScrollWidth.current
    ) {
      setCurrentIndex((prevState) => prevState + 1);
    }
  };

  const isDisabled = (direction) => {
    if (direction === "prev") {
      return currentIndex <= 0;
    }

    if (direction === "next" && listCarousel.current !== null) {
      return (
        listCarousel.current.offsetWidth * currentIndex >= maxScrollWidth.current
      );
    }

    return false;
  };

  useEffect(() => {
    if (listCarousel !== null && listCarousel.current !== null) {
        listCarousel.current.scrollLeft = listCarousel.current.offsetWidth * currentIndex;
    }
  }, [currentIndex]);

  useEffect(() => {
    maxScrollWidth.current = listCarousel.current
      ? listCarousel.current.scrollWidth - listCarousel.current.offsetWidth
      : 0;
  }, []);
  const DisplayData = ShowList.map((value, itemIndex) => {
    let imageList = value.Shows.map((item) => {
      return item;
      
    });
    return (
      <section>
        <div 
        ref={containerCarousel}
        className="carousel my-12 mx-auto"
        >
          <h1 className="text-3xl leading-8 font-bold mb-12 text-slate-700">
            {value.name}
          </h1>
          <div 
          className="relative overflow-hidden">
            <div className="flex justify-between absolute top left w-full h-full">
              <button
                onClick={movePrev}
                className="hover:bg-blue-900/75 text-white w-10 h-full text-center opacity-75 hover:opacity-100 disabled:opacity-25 disabled:cursor-not-allowed z-10 p-0 m-0 transition-all ease-in-out duration-300"
                disabled={isDisabled("prev")}
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="h-12 w-20 -ml-5"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  strokeWidth={2}
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M15 19l-7-7 7-7"
                  />
                </svg>
                <span className="sr-only">Prev</span>
              </button>
              <button
                onClick={moveNext}
                className="hover:bg-blue-900/75 text-white w-10 h-full text-center opacity-75 hover:opacity-100 disabled:opacity-25 disabled:cursor-not-allowed z-10 p-0 m-0 transition-all ease-in-out duration-300"
                disabled={isDisabled("next")}
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="h-12 w-20 -ml-5"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  strokeWidth={2}
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M9 5l7 7-7 7"
                  />
                </svg>
                <span className="sr-only">Next</span>
              </button>
            </div>
            <div
              ref={listCarousel}
              className="carousel-container relative flex gap-1 overflow-hidden scroll-smooth snap-x snap-mandatory touch-pan-x z-0"
            >
              {imageList.map((img, index) => {
                return (
                  <ul>
                    <li 
                    key={index}
                    className="carousel-item text-center  relative w-64 h-64 snap-start"
                    >
                      <a
                        href={img.link}
                        className="h-full w-full aspect-square block bg-origin-padding bg-left-top bg-cover bg-no-repeat z-0"
                        style={{ backgroundImage: `url(${img.image || ""})` }}
                      >
                        <img
                          src={img.image || ""}
                          alt={img.title}
                          className="w-full rounded aspect-square hidden"
                        />
                      </a>
                      <a
                        href={img.link}
                        className="h-full w-full aspect-square block absolute top-0 left-0 transition-opacity duration-300 opacity-0 hover:opacity-100 bg-blue-800/75 z-10"
                      >
                        <h3 className="text-white py-6 px-3 mx-auto text-xl">
                          {img.title}
                        </h3>
                      </a>
                    </li>
                  </ul>
                );
              })}
            </div>
          </div>
        </div>
      </section>
    );
  });
  return <div>{DisplayData}</div>;
}

here is my data json file:

https://drive.google.com/file/d/1G0wInErDa2bUHGjn-TNDfTVXJru0QlaY/view?usp=sharing

0 Answers
Related