skip to Main Content

I’m building a carousel component and I need it to scroll when the user presses the navigation buttons, so far my code is like this but the scroll is not working :

import React, { FC, useRef, useEffect, useState } from "react";

const Carousel: FC = () => {
  const [activeSlide, setActiveSlide] = useState(0);
  const slides = Array.from({ length: 6 }, (_, index) => ({
    data: `Slide ${index + 1}`
  }));

  const containerRef = useRef<HTMLDivElement>(null);
  const slideRefs = useRef<HTMLDivElement[]>([]);

  const isLeftEnabled = activeSlide !== 0;
  const isRightEnabled = activeSlide !== slides.length - 1;

  useEffect(() => {
    if (containerRef.current) {
      containerRef.current.scrollTo(500, 0);
      console.log("scroll");
      console.log("containerRef.current", containerRef.current);
      //console all variables one by one
    }
  }, [activeSlide, slides]);

  return (
    <div className="flex flex-col items-center w-3/5">
      <div className="w-full overflow-x-scroll overflow-y-hidden carousel-container">
        <div className="flex gap-10 w-screen mb-8" ref={containerRef}>
          {slides.map((slide, index) => (
            <div
              className={`slide ${
                activeSlide === index ? "bg-purple-500" : "bg-green-400"
              } rounded-2xl h-52 w-40 flex place-items-center
    select-none`}
              key={`slide-${index}`}
            >
              <p className="m-auto">{slide.data}</p>
            </div>
          ))}
        </div>
      </div>
      <div className="flex gap-6">
        <button
          onClick={() => {
            isLeftEnabled && setActiveSlide(activeSlide - 1);
          }}
          className={`rounded-full w-20 h-20 ${
            isLeftEnabled ? "bg-green-600" : "bg-gray-300"
          }`}
        >
          ◀
        </button>
        <button
          onClick={() => {
            isRightEnabled && setActiveSlide(activeSlide + 1);
          }}
          className={`rounded-full w-20 h-20 ${
            isRightEnabled ? "bg-green-600" : "bg-gray-300"
          }`}
        >
          ▶
        </button>
      </div>
    </div>
  );
};

export default Carousel;

I have created a codesandbox with the problem :

https://codesandbox.io/s/carousel-scroll-problem-9solvt?file=/src/Carousel.tsx:0-2022

3

Answers


  1. Since the element you specify containerRef is not scrollable specify the element with class overflow-x-scroll (parent of current containerRef) as ref={containerRef} it will work

    Login or Signup to reply.
  2. You have the ref set on the wrong container. It should be the parent, as it has the overflow-x-scroll class.

    <div className="w-full overflow-x-scroll overflow-y-hidden carousel-container" 
         ref={containerRef}>
    
    Login or Signup to reply.
  3. some modifications that you’ll have to do:

        useEffect(() => {
        if (containerRef.current) {
    // modify below logic by calculating the width and scroll position of container
          if (activeSlide === 2) containerRef.current.scrollTo(0, 0);
          if (activeSlide === 3) containerRef.current.scrollTo(500, 0);
    
          console.log("scroll");
          console.log("containerRef.current", containerRef.current);
          //console all variables one by one
        }
      }, [activeSlide, slides]);
    

    the template:

        ...<div className="w-full overflow-x-scroll overflow-y-hidden carousel-container" ref={containerRef}>
        <div className="flex gap-10 w-screen mb-8">...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search