DEV Community

Cover image for Simple React Projects || Image Slider
TD!
TD!

Posted on

Simple React Projects || Image Slider

It's Day #8 of the #100daysofMiva coding challenge. See codes on GitHub

Today, I worked on a simple image slider project using React. The project involved fetching images from an external API and displaying them in a slider format, where users can navigate through the images using left and right arrow buttons. Below is a breakdown and analysis of the code and what I learned from this experience.

Code Analysis

Let's break down the code step by step:

1. Import Statements


import { useEffect, useState } from "react";
import { BsArrowLeftCircleFill, BsArrowRightCircleFill } from "react-icons/bs";
import "./styles.css";
Enter fullscreen mode Exit fullscreen mode

useEffect and useState are hooks provided by React to handle side effects and state management, respectively.

BsArrowLeftCircleFill and BsArrowRightCircleFill are icon components imported from the react-icons library. These are used to display the navigation arrows.

./styles.css imports the CSS file that contains the styles for the slider.

2. Component Definition


export default function ImageSlider({ url, limit = 5, page = 1 }) {
  const [images, setImages] = useState([]);
  const [currentSlide, setCurrentSlide] = useState(0);
  const [errorMsg, setErrorMsg] = useState(null);
  const [loading, setLoading] = useState(false);
Enter fullscreen mode Exit fullscreen mode

ImageSlider is a React functional component that receives three props: url, limit, and page. The url prop specifies the API endpoint to fetch images from. limit and page are optional props with default values, determining how many images to fetch and which page of the API to request.

Four pieces of state are managed using useState:

images: Stores the fetched image data.
currentSlide: Tracks the currently displayed image.
errorMsg: Stores any error message if the image fetching fails.
loading: Indicates whether the images are currently being loaded.

3. Fetching Images


async function fetchImages(getUrl) {
  try {
    setLoading(true);

    const response = await fetch(`${getUrl}?page=${page}&limit=${limit}`);
    const data = await response.json();

    if (data) {
      setImages(data);
      setLoading(false);
    }
  } catch (e) {
    setErrorMsg(e.message);
    setLoading(false);
  }
}
Enter fullscreen mode Exit fullscreen mode

fetchImages is an asynchronous function that fetches image data from the provided API url.

setLoading(true) is called before the fetch to indicate that data is being loaded.

The fetch function retrieves the data from the API, and await response.json() parses it into a JavaScript object. If data is successfully fetched, it is stored in the images state.
If an error occurs, setErrorMsg is called to store the error message, and loading is stopped.

4. Navigating Between Images


function handlePrevious() {
  setCurrentSlide(currentSlide === 0 ? images.length - 1 : currentSlide - 1);
}

function handleNext() {
  setCurrentSlide(currentSlide === images.length - 1 ? 0 : currentSlide + 1);
}
Enter fullscreen mode Exit fullscreen mode

handlePrevious and handleNext are functions to navigate through the images.

handlePrevious decreases the currentSlide index unless it’s at the first image, in which case it loops back to the last image.

handleNext increases the currentSlide index unless it’s at the last image, in which case it loops back to the first image.

5. Fetching Images on Component Mount


useEffect(() => {
  if (url !== "") fetchImages(url);
}, [url]);
Enter fullscreen mode Exit fullscreen mode

useEffect is used to run fetchImages when the component mounts or whenever the url prop changes. This ensures that new images are fetched if the url changes.

6. Rendering the Component


if (loading) {
  return <div>Loading data! Please wait</div>;
}

if (errorMsg !== null) {
  return <div>Error occurred! {errorMsg}</div>;
}
Enter fullscreen mode Exit fullscreen mode

If loading is true, a loading message is displayed. If errorMsg contains a value, the error message is displayed.

7. Image Slider Display


return (
  <div className="container">
    <BsArrowLeftCircleFill
      onClick={handlePrevious}
      className="arrow arrow-left"
    />
    {images && images.length
      ? images.map((imageItem, index) => (
          <img
            key={imageItem.id}
            alt={imageItem.download_url}
            src={imageItem.download_url}
            className={
              currentSlide === index
                ? "current-image"
                : "current-image hide-current-image"
            }
          />
        ))
      : null}
    <BsArrowRightCircleFill
      onClick={handleNext}
      className="arrow arrow-right"
    />
    <span className="circle-indicators">
      {images && images.length
        ? images.map((_, index) => (
            <button
              key={index}
              className={
                currentSlide === index
                  ? "current-indicator"
                  : "current-indicator inactive-indicator"
              }
              onClick={() => setCurrentSlide(index)}
            ></button>
          ))
        : null}
    </span>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

The main slider is rendered within a div with the class container. The left and right arrows call handlePrevious and handleNext respectively to change the displayed image. The current image is shown using an img tag, and non-current images are hidden using the hide-current-image class. Circle indicators below the images represent each slide, and the active slide is highlighted.

CSS Analysis

The CSS is used to style the slider:

.container: Centers the content and sets the slider size.
.current-image
: Styles the displayed image.
.arrow: Positions the navigation arrows.
.circle-indicators: Positions the indicator buttons at the bottom.
.current-indicator: Styles the active slide indicator.
.hide-current-image: Hides non-active images.
.inactive-indicator: Styles the inactive slide indicators.

Top comments (2)

Collapse
 
marvellye profile image
Ezekiel Marvellous

Beautiful 🪄

Collapse
 
tobidelly profile image
TD!

Thank you