How to build a Fullscreen Slider with React Hooks
Tags: react, javascript, beginners
Published: 2020-03-24 17:02:03

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](https://www.ibrahima-ndaw.com/blog/react-fullscreen-slider/)_

- [Plan our app](#plan-our-app)
- [Creating the custom hook](#creating-the-custom-hook)
- [Display the slider](#display-the-slider)

## 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:

```shell
npx create-react-app react-fullscreen-slider
```

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
```

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`

```jsx
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'
    }
]
```

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](https://media.giphy.com/media/ckeHl52mNtoq87veET/source.gif)

## 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`

```jsx
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;
}
```

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`

```jsx
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);
}
```

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`

```jsx
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
```

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](https://media.giphy.com/media/3ohzdIuqJoo8QdKlnW/source.gif)

## 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`

```jsx
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;
```

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](https://github.com/ibrahima92/react-fullscreen-slider). 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`

```jsx
import React from 'react';
import Slider from './components/Slider'
import Images from './images'

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

export default App;
```

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](https://drive.google.com/uc?id=1cqQKM3stsHue4sYybBeZjppx8kI-2Vp-)

Thanks for reading!

You can find the source code [here](https://github.com/ibrahima92/react-fullscreen-slider)

| [TWITTER](https://twitter.com/ibrahima92_) | [BLOG](https://www.ibrahima-ndaw.com/) | [NEWSLETTER](https://ibrahima-ndaw.us5.list-manage.com/subscribe?u=8dedf5d07c7326802dd81a866&id=5d7bcd5b75) | [GITHUB](https://github.com/ibrahima92) | [LINKEDIN](https://www.linkedin.com/in/ibrahima-ndaw/) | [CODEPEN](https://codepen.io/ibrahima92) | [DEV](https://dev.to/ibrahima92) |
| -------------- | ------------------------------------------ | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------- | ------------------------------------------------------ | ---------------------------------------- | -------------------------------- |