DEV Community

 Theodora Cristea
Theodora Cristea

Posted on

Build Your Own Infinite Carousel in React (with a Custom Hook)❗

Hey!🥰 It’s been a while since my last post…
No ofcorse, I haven’t quit web development,🙃 and nope, I didn’t go on a long vacation either.🙃 Quite the opposite - I’ve been coding non-stop, 6 out of 7 days. I’ve been busy with a project that I’ll share with you soon, but today I want to show you something smaller but really useful:

➤ How I built a reusable infinite carousel in React, using only a custom hook, a component, and some CSS.
GitHub: Carousel
Demo: Carousel


Why another carousel❓

Carousels are everywhere: online shops, landing pages, portfolios… and let’s be honest, many developers reach for a big library when all they need is a simple slider.

There’s nothing wrong with libraries, but sometimes it’s good to be curious and understand the logic behind them. Building one yourself gives you full control and help you creating your own mini-library.


What does an infinite carousel mean❓

A classic carousel has a beginning and an end. If you reach the last image and click “next,” it either stops or jumps back abruptly. An infinite carousel creates the illusion that the list never ends.
How❓

Clone a few slides and add them to the beginning and end.
When you move too far left or right, instantly reposition the list without the user noticing. This trick gives the user the feeling they can scroll endlessly.
Sounds a bit confusing❓Don’t worry, keep reading and it will all make sense.🥰


Project structure:

I split the logic into two parts:
InfiniteCarousel component ➤ handles the UI (images, titles, navigation buttons).
useCarousel hook ➤ handles the logic (clones, index, transitions, auto-slide, resize).
This makes the carousel reusable: you can drop the hook into any React project and use it with any type of content.


The useCarousel hook

The hook accepts a few configuration options:

useCarousel({
  visibleSlides: 4,           // how many slides are visible at once
  gap: 32,                    // spacing between them
  autoSlideInterval: 3000,    // autoplay interval in ms
});
Enter fullscreen mode Exit fullscreen mode

What it does under the hood

Index tracking: ➤ keeps track of the current position with a ref.
Transitions ➤ moves the carousel with translateX.
Invisible reset ➤ when you go past the edges, it disables transition, instantly repositions, then continues normally.
Auto-slide ➤ moves slides automatically, pauses on hover.
Resize handler ➤ recalculates slide widths when the window size changes.

The InfiniteCarousel component

The UI is quite straightforward:
• ul for the list of slides,
• li for each image,
• two buttons for manual navigation.


Responsive design

With some media queries, the carousel adapts to different screen sizes:
• On mobile → 1–2 slides visible,
• On tablet → 3 slides,
• On desktop → 4 slides.

@media screen and (min-width: 500px) {
  .li-right-tea {
    width: calc(50% - 32px / 2);
  }
}

@media screen and (min-width: 900px) {
  .li-right-tea {
    width: calc(33.33% - 64px / 3);
  }
}

@media screen and (min-width: 1200px) {
  .li-right-tea {
    width: calc(25% - 96px / 4);
  }
}
Enter fullscreen mode Exit fullscreen mode

Visual scheme of the logic

Let’s say we have 8 original slides: A B C D E F G H We want 4 visible at once ➤ that means we clone 4 at the beginning and 4 at the end.

Key positions:

Start (index = 4) ➤ aligned on the first real slide (A)
Visible: [ A | B | C | D ]
Going right (next):
You reach index 11 (H).
Next click ➤ index 12 (A clone).
➤ On transitionend, it instantly resets back to index 4 (A real).
Going left (prev):
You reach index 3 (H clone).
➤ On transitionend, it instantly resets back to index 11 (H real).
The user never sees the*jump* The illusion of infinity is preserved.


Final functionality

• Manual navigation with buttons,
• Auto-slide with customizable interval,
• Pause on hover,
• Invisible reset for infinite effect,
• Responsive (media queries + resize recalculation),
• Reusable (hook works with any type of content, not just images).


Conclusion❤️

Now you have a fully working infinite carousel in React, built from scratch, with no external libraries, and with full control over the behavior.🥰Of course, it can be enhanced with indicators (dots) for progress, animations, and other functionalities! I think building your own mini-libraries in React is worth it. You not only learn how things work under the hood, but you also get the freedom to extend and customize them however you like.

I hope this post helps you!🥰 For me, rewriting it was a great way to solidify my understanding. Let me know in the comments if you have questions or if this was useful for you.
Happy coding!


Top comments (2)

Collapse
 
uzzy412_73 profile image
Alexandru Ene

Hey, nice one! You made a good job on reusability. I think I might borrow it. With your permission, of course! :)

Collapse
 
cristea_theodora_6200140b profile image
Theodora Cristea

Thank you so much! Is not the perfect one, but is working🙃 I'm so glad to hear that! 🥰 You have my permission, of course!🤗 I hope will be helpful for you! Happy codding!🙃