How to build a Fullscreen Slider with React Hooks

Ibrahima Ndaw - Mar 24 '20 - - Dev Community

In this tutorial, we will build a Fullscreen Slider component with React Hooks.
And to do that, we will create a custom hook to handle all the logic, then use it as a helper method to display the slides.

So, let's start by planning how our app will look like.

Originally posted on my blog

Plan our app

To be able to follow along, you have to create a brand new React app by running the following command on your terminal:

npx create-react-app react-fullscreen-slider
Enter fullscreen mode Exit fullscreen mode

Next, structure your project as follow:

├── App.js
├── App.test.js
├── components
|  └── Slider.js
├── hooks
|  └── useSlider.js
├── images.js
├── index.css
├── index.js
├── logo.svg
├── serviceWorker.js
└── setupTests.js
Enter fullscreen mode Exit fullscreen mode

As you can see, the folder structure is very simple. We have a components folder which holds a file named Slider.js, and another folder hooks which keeps as you might guess the custom hook useSlider, and an images.js file which contain the images to show on the slider.

Now, let's add some lines of code into these files.

  • images.js
export default [
    {
     src: 'https://drive.google.com/uc?id=1_oA9Sx4D4DhFrYBFQdL0I1CUIz_LhQue',
     text: 'Duis aute irure dolor in reprehenderit in voluptate velit esse'
    },
    {
     src: 'https://drive.google.com/uc?id=1rJFs-8So16UCiDag__hG4yyf_RnC08Fa',
     text: 'Consectetur adipisicing elit cillum dolore eu fugiat nulla'
    },
    {
     src: 'https://drive.google.com/uc?id=1HO2AGjd_1yyYI4pYTTBmGXBaWHoGSqCl',
     text: 'Asperiores ex animi explicabo cillum dolore eu fugiat nulla'
    }
]
Enter fullscreen mode Exit fullscreen mode

As I said earlier, this file holds the images. And each object has an image and a description. By the way, you can use a different approach to declare your images, it's totally up to you.

We have now the data to show, it's time to build the custom hook to handle the logic of the slider.

Let's do that

excited

Creating the custom hook

The useSlider function will receive three arguments: the image of the slide, the description and an array of images.

  • hooks/useSlider.js
import { useEffect } from 'react'

const useSlider = (slideImage, slideText, images) => {
 let slideCounter = 0;

 useEffect(() => startSlider())

 const startSlider =() => {
    slideImage.current.style.backgroundImage = `linear-gradient(
        to right,
        rgba(34, 34, 34, 0.4),
        rgba(68, 68, 68, 0.4)
        ), url(${images[0].src})`;
        slideText.current.innerHTML = images[0].text;
}
Enter fullscreen mode Exit fullscreen mode

With these parameters in place, we can now create a new function startSlider() and handle the first slide to display when the page finished loading.

Later, we will use useRef to select elements and be able to manipulate the DOM (Document Object Model). But for now, just keep in mind that slideImage and slideText are references to DOM elements.

We can now access to the properties of these elements and start styling it. Here, we apply a linear gradient to the image, to well have a nice looking style, and next, append the corresponding text to the DOM.

  • hooks/useSlider.js
const handleSlide = (slide) => {
 slideImage.current.style.backgroundImage = `linear-gradient(
    to right,
    rgba(34, 34, 34, 0.4),
    rgba(68, 68, 68, 0.4)
    ), url(${images[slide - 1].src})`;
    slideText.current.innerHTML = images[slide - 1].text;
    animateSlide(slideImage)
}

const animateSlide = () => {
 slideImage.current.classList.add('fadeIn');
  setTimeout(() => {
    slideImage.current.classList.remove('fadeIn');
  }, 700);
}
Enter fullscreen mode Exit fullscreen mode

Next, we use the same method with the function handleSlide() by applying a linear gradient to the image. But this time, we receive as a parameter the number of the slide or counter if you want too, then use it to show the appropriate slide on the screen.

Next, we call the animateSlide() method to well, animate it with a nice fade-in effect.

  • hooks/useSlider.js
const goToPreviousSlide = () => {
  if (slideCounter === 0) {
    handleSlide(images.length)
    slideCounter = images.length;
  }

    handleSlide(slideCounter)         
    slideCounter--;
  }

const goToNextSlide = () => {
  if (slideCounter === images.length - 1) {
    startSlider()
    slideCounter = -1;
    animateSlide(slideImage)
  }

 slideImage.current.style.backgroundImage = `linear-gradient(
        to right,
        rgba(34, 34, 34, 0.4),
        rgba(68, 68, 68, 0.4)
        ),url(${images[slideCounter + 1].src})`;
    slideText.current.innerHTML = images[slideCounter + 1].text;
    slideCounter++;
      animateSlide(slideImage)
}

return { goToPreviousSlide, goToNextSlide }
}

export default useSlider
Enter fullscreen mode Exit fullscreen mode

As you can see, here, we have two main functions: goToPreviousSlide() and goToNextSlide().

The first method goToPreviousSlide() will check if the counter of the slide is equal to 0. And If it's the case, it will show the last slide, otherwise, it displays the previous one.

The second method will do the opposite. It checks if the counter of slides is equal to the last one and if it's the case, it will restart the slider, otherwise, the goToNextSlide() method will show the next slide.

And to make everything accessible from another file, we have to return an object which contains goToPreviousSlide() and goToNextSlide().

That being said, we can now move to the final part and use the custom hook to display the slider in the next section.

awesome

Display the slider

We already have the logic to show the slides, the only thing we have to do now is displaying them with Slider.js.

  • Slider.js
import React, { useRef } from 'react';
import useSlider from '../hooks/useSlider'

const Slider = ({images}) => {

  const slideImage = useRef(null)
  const slideText = useRef(null)
  const { goToPreviousSlide, goToNextSlide } = useSlider(slideImage, slideText, images)

  return (
    <div className="slider" ref={slideImage}>
      <div className="slider--content">
        <button onClick={goToPreviousSlide} className="slider__btn-left">
        <i className="fas fa-angle-left"></i>
        </button>
        <div className="slider--feature">
          <h1 className="feature--title">Dreaming</h1>
          <p ref={slideText} className="feature--text"></p>
          <button className="feature__btn">Get started</button>
        </div>
        <button onClick={goToNextSlide} className="slider__btn-right">
        <i className="fas fa-angle-right"></i>
        </button>
     </div>
    </div>
    );
}

export default Slider;
Enter fullscreen mode Exit fullscreen mode

I forgot to mention it, but the CSS part will be not covered in this article, you can still find it in the Source Code. So, don't let these class names disturbing you.

The Slider() function is relatively easy to implement since we already have useSlider.

The only thing we have to do is importing useSlider, then pull goToPreviousSlide() and goToNextSlide() without forgetting to pass the parameters as arguments to the function.

And as I said earlier, we have to use useRef to access DOM elements.

With that change, we can now use the Slider component in the App.js file and pass down the images array as props.

  • App.js
import React from 'react';
import Slider from './components/Slider'
import Images from './images'

function App() {
  return (
    <Slider images={Images}  />
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

And as you can see here, we just import the Images and pass them as props to the Slider component.

With this tiny update, we have now done building a Fullscreen Slider component using React Hooks.

slider

Thanks for reading!

You can find the source code here

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .