How to make a dynamic grid like carousel in React js with multiple items in a single slide?

Viewed 88

A carousel with 5 different items in one slide

I am looking to create a carousel like this with its images being fetched out of an API in React js. I was searching for a ready made carousel like this online but couldn't find one. I want to be able to show the fetched image URL's in these sections and then automatically create a new carousel slide if I have more than 5 images. I am new to react so please help me out with this. I currently have a normal carousel from react-bootstrap

`

<Carousel className="gh78">
                    {trending.map((item, index) => (
                          <Carousel.Item key={index}>
                            <div className="LiveStats46">
                              <div className="Live24">
                                <samp className="blink"></samp>
                                {item.video_type}
                              </div>
                              <div className="Views24">
                                <span className="fas fa-user"></span>
                                {item.watching_count}
                              </div>
                            </div>
                            <Link href={"/live-streaming/" + item.streamkey}>
                              <a>
                                <div className="trenvid23">
                                  {item.video_image ? (
                                    <img
                                      src={item.video_image}
                                      alt="terndingimage"
                                    ></img>
                                  ) : (
                                    <img
                                      src="https://d25u15mvjkult8.cloudfront.net/Website/Assets/Images/gameseedefault.png"
                                      alt="trending"
                                    ></img>
                                  )}
                                </div>
                              </a>
                            </Link>
                          </Carousel.Item>
                        ))}
                  </Carousel>`

This is how mine looks currently

1 Answers

You can slice() the data you receive based on the chunk size (here it's 5 as that's how many images you want per slide) and the index of the carousel (which slide are we on) :

  const [allImages, setAllImages] = useState([]);
  const [imagesToDisplay, setImagesToDisplay] = useState([]);
  const [index, setIndex] = useState(1);
  const chunkSize = 5;

  // Retrieve data
  useEffect(() => {
    setAllImages([
      { name: "Image 1",  link: "/image1" },
      { name: "Image 2",  link: "/image2" },
      { name: "Image 3",  link: "/image3" },
      { name: "Image 4",  link: "/image4" },
      { name: "Image 5",  link: "/image5" },
      { name: "Image 6",  link: "/image6" },
      { name: "Image 7",  link: "/image7" },
      { name: "Image 8",  link: "/image8" },
      { name: "Image 9",  link: "/image9" },
      { name: "Image 10", link: "/image10" },
      { name: "Image 11", link: "/image11" }
    ]);
  }, []);

  // Slice the data
  useEffect(() => {
    setImagesToDisplay(
      allImages.slice(
        chunkSize * index - chunkSize,
        chunkSize * index
      )
    );
  }, [allImages, index]);

  // Go previous index
  const handleSubstractIndex = () => {
    setIndex((prevIndex) => prevIndex - 1);
  };
  // Go next index
  const handleAddIndex = () => {
    setIndex((prevIndex) => prevIndex + 1);
  };

  return (
    <>
      <div
        style={{
          display: "grid",
          gridTemplateColumns: "1fr 3fr 1fr",
          gridTemplateRows: "2fr 1fr"
        }}
      >
        {imagesToDisplay.map((image) => (
          <div
            className="carousel"
            key={image.link}
            style={{ border: "1px solid orange" }}
          >
            {image.name}
          </div>
        ))}
      </div>
      <button onClick={() => handleSubstractIndex()}>previous</button>
      <button onClick={() => handleAddIndex()}>next</button>
    </>
  );

Edit carousel with multiple images

I would then animate the carousel using Framer Motion, React Spring or whatever animation library you use that supports animating while unmounting.

Now of course there are other ways to achieve this, that's just how I personally would do it as it fits well into my projects.

You can also add more logic to reset the carousel while reaching the end.

Related