How to Build a React Carousel Component

When I first started building web applications over eight years ago, creating a smooth image slider was a rite of passage for any frontend developer.

Carousels are everywhere in modern UI design, from showcasing featured real estate listings in New York to displaying top-rated national parks across the US.

In this tutorial, I will show you exactly how to implement a React carousel component using two different professional methods.

Whether you want to build one from scratch for full control or use a robust library to save time, I have you covered.

Method 1: Build a Custom React Carousel from Scratch

I often prefer building my own components when I need a lightweight solution without the overhead of external dependencies.

This approach gives you total control over the transitions, styling, and accessibility features of your slider.

For this example, let’s imagine we are building a “Featured US Travel Destinations” slider for a tourism website.

Set Up the Component Structure

First, we need to define our data. I’ll use an array of objects containing images of iconic American landmarks like the Grand Canyon and the Statue of Liberty.

Here is the complete code for a functional, state-driven carousel:

import React, { useState, useEffect } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';

const US_DESTINATIONS = [
  {
    id: 1,
    title: "Grand Canyon National Park",
    location: "Arizona",
    url: "https://images.unsplash.com/photo-1474044159687-1ee9f3a51722?auto=format&fit=crop&w=800&q=80"
  },
  {
    id: 2,
    title: "Statue of Liberty",
    location: "New York",
    url: "https://images.unsplash.com/photo-1518391846015-55a9cc003b25?auto=format&fit=crop&w=800&q=80"
  },
  {
    id: 3,
    title: "Golden Gate Bridge",
    location: "San Francisco, CA",
    url: "https://images.unsplash.com/photo-1449034446853-66c86144b0ad?auto=format&fit=crop&w=800&q=80"
  }
];

const CustomCarousel = () => {
  const [currentIndex, setCurrentIndex] = useState(0);

  const prevSlide = () => {
    const isFirstSlide = currentIndex === 0;
    const newIndex = isFirstSlide ? US_DESTINATIONS.length - 1 : currentIndex - 1;
    setCurrentIndex(newIndex);
  };

  const nextSlide = () => {
    const isLastSlide = currentIndex === US_DESTINATIONS.length - 1;
    const newIndex = isLastSlide ? 0 : currentIndex + 1;
    setCurrentIndex(newIndex);
  };

  // Optional: Auto-play functionality
  useEffect(() => {
    const slideInterval = setInterval(nextSlide, 5000);
    return () => clearInterval(slideInterval);
  }, [currentIndex]);

  return (
    <div className="max-w-[800px] h-[500px] w-full m-auto py-16 px-4 relative group">
      <div
        style={{ backgroundImage: `url(${US_DESTINATIONS[currentIndex].url})` }}
        className="w-full h-full rounded-2xl bg-center bg-cover duration-500 shadow-xl"
      >
        <div className="absolute bottom-5 left-5 text-white bg-black/50 p-4 rounded-lg">
          <h2 className="text-xl font-bold">{US_DESTINATIONS[currentIndex].title}</h2>
          <p>{US_DESTINATIONS[currentIndex].location}</p>
        </div>
      </div>

      {/* Left Arrow */}
      <div className="hidden group-hover:block absolute top-[50%] -translate-x-0 translate-y-[-50%] left-5 text-2xl rounded-full p-2 bg-black/20 text-white cursor-pointer">
        <ChevronLeft onClick={prevSlide} size={30} />
      </div>

      {/* Right Arrow */}
      <div className="hidden group-hover:block absolute top-[50%] -translate-x-0 translate-y-[-50%] right-5 text-2xl rounded-full p-2 bg-black/20 text-white cursor-pointer">
        <ChevronRight onClick={nextSlide} size={30} />
      </div>

      <div className="flex top-4 justify-center py-2">
        {US_DESTINATIONS.map((slide, slideIndex) => (
          <div
            key={slideIndex}
            onClick={() => setCurrentIndex(slideIndex)}
            className={`text-2xl cursor-pointer mx-1 ${currentIndex === slideIndex ? 'text-blue-600' : 'text-gray-400'}`}
          >
            ●
          </div>
        ))}
      </div>
    </div>
  );
};

export default CustomCarousel;

You can see the output in the screenshot below.

Build a React Carousel Component

In this implementation, I use the useState hook to keep track of the active slide index.

The prevSlide and nextSlide functions handle the logic for looping back to the start or end of the array.

I also added an useEffect hook to enable auto-play, which is common on professional US retail sites.

The styling uses Tailwind CSS classes, but you can easily swap these for standard CSS modules or Styled Components.

Method 2: Implement Carousel Using React-Slick

When I am working on a deadline or need advanced features like touch-swiping for mobile users, I turn to react-slick.

It is one of the most popular libraries in the React ecosystem for creating robust sliders.

For this example, let’s build a “Trending Tech Jobs in the USA” slider that might appear on a professional networking dashboard.

Installation

First, you need to install the package and its CSS files:

npm install react-slick slick-carousel

Implementation Code

Here is how I typically set up a react-slick component with custom settings:

import React from "react";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";

const JobCard = ({ title, company, location, salary }) => (
  <div className="p-4">
    <div className="bg-white border rounded-lg p-6 shadow-md hover:shadow-lg transition-shadow">
      <h3 className="text-lg font-semibold text-slate-800">{title}</h3>
      <p className="text-blue-600">{company}</p>
      <p className="text-gray-500 text-sm">{location}</p>
      <div className="mt-4 font-bold text-green-600">{salary}</div>
      <button className="mt-4 w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-700">
        Apply Now
      </button>
    </div>
  </div>
);

const TechJobsCarousel = () => {
  const settings = {
    dots: true,
    infinite: true,
    speed: 500,
    slidesToShow: 3,
    slidesToScroll: 1,
    responsive: [
      {
        breakpoint: 1024,
        settings: {
          slidesToShow: 2,
          slidesToScroll: 1,
        }
      },
      {
        breakpoint: 600,
        settings: {
          slidesToShow: 1,
          slidesToScroll: 1
        }
      }
    ]
  };

  const jobs = [
    { title: "Senior React Developer", company: "TechCorp", location: "Austin, TX", salary: "$140k - $180k" },
    { title: "Frontend Engineer", company: "CloudScale", location: "Seattle, WA", salary: "$130k - $160k" },
    { title: "Full Stack Developer", company: "FinTech Solutions", location: "Charlotte, NC", salary: "$120k - $150k" },
    { title: "UI/UX Developer", company: "DesignHub", location: "Remote, US", salary: "$110k - $140k" }
  ];

  return (
    <div className="max-w-6xl mx-auto px-4 py-12">
      <h2 className="text-3xl font-bold mb-8 text-center text-slate-900">
        Trending Developer Roles in the US
      </h2>
      <Slider {...settings}>
        {jobs.map((job, index) => (
          <JobCard key={index} {...job} />
        ))}
      </Slider>
    </div>
  );
};

export default TechJobsCarousel;

You can see the output in the screenshot below.

How to Build a React Carousel Component

In my experience, libraries like react-slick are essential when you need complex responsive behavior.

In the code above, the responsive array allows the carousel to show three cards on desktop but drop to one on smartphone.

This ensures that your US-based users have a seamless experience, whether they are browsing on a MacBook Pro or an iPhone.

The library handles the “swipe” math for you, which is notoriously difficult to get right when coding from scratch.

Key Considerations for React Carousels

When you are implementing these components, keep these professional tips in mind:

Performance Optimization

I always recommend lazy-loading images within a carousel, especially if you have more than five slides.

Loading ten high-resolution images of “San Francisco Sunsets” at once will significantly hurt your PageSpeed Insights score.

Accessibility (a11y)

In the US, ensuring your website is ADA compliant is not just good practice, it’s often a legal requirement.

Make sure your buttons have aria-labels and that the carousel can be navigated using only a keyboard.

I’ve seen many developers forget to add focus states to the “Next” and “Previous” buttons, which makes the site unusable for screen readers.

Image Ratios

One common headache I encounter is mismatched image sizes.

If your “Grand Canyon” photo is a portrait and your “Statue of Liberty” photo is a landscape, the carousel will “jump” in height.

Always use a consistent aspect ratio (like 16:9) or use the CSS property object-fit: cover to maintain a uniform look.

I hope you found this tutorial on implementing a React carousel helpful.

Using these methods will allow you to create professional, high-performing sliders for any US-based web project.

You may also like to read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.