DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Working with React Hooks: How to build a slider
Emmanuel Ugwu
Emmanuel Ugwu

Posted on

Working with React Hooks: How to build a slider

Hooks solve a wide variety of problems in React that have been encountered while writing and maintaining components. Whether you’re learning React or even prefer a different library with a similar component model, you might recognize some of these problems.
React Hooks simply let you use React features without writing a class component. In other words, Hooks are functions that let you use React state and lifecycle features from function components. It is assumed that you have an immediate knowledge of React and Node.js. Now, let’s get started.

Getting Started

If you have NPM and Node.js installed, create a React project in a new folder called review-slider and install react-icons in its directory:

npx create-react-app review-slider 
cd review-slider
# Install react-icons
npm install react-icons
Enter fullscreen mode Exit fullscreen mode

Running npm start will render the React application with a confirmatory message on your browser:
React confirmatory message

Defining our components

First off, let’s split the structure of our project into two independent components for improved performance and maintainability.

  • App.js - Contains the main body of our slider, its React Hooks, and the slider buttons
  • People.js - This contains the destructuring process of our data array to display the slider content.

Declaring state variables

A state variable, people is declared and set to the data in the data.js file. For the slider’s functionality, there will have to be an index that changes as soon as a button is clicked. This means we'll also declare another state variable for the index of our data, with an initial value of 0.
This is where the React Hooks features come in into play, useState is a new way to use the exact same capabilities that this.state provides in a class. It preserves some values of a variable between function calls. Normally, variables disappear when the function exits but state variables are preserved. Another feature is useEffect which we will apply later on to have some form of functionality.

//App.js
import React, {useState, useEffect} from 'react';
import data from './data';
function App() {
  const [people, setPeople] = useState(data);
  const [index, setIndex] = useState(0);
  }
  export default App;
Enter fullscreen mode Exit fullscreen mode

Destructuring our properties

Rendering a list of data

Using a map() function, we’ll iterate through the data from data.js, with the aim of destructuring its properties and then return the React component, People with its props.

//App.js
function App() {
return (
<section className="section">
<div className="title">
 <h2>reviews</h2>
 <div className="underline"></div>
</div>
<div className="section-center">
  {people.map((person, personIndex) => {
  return <People key={person.id} {...person} personIndex= 
  {personIndex} index={index} />
      })}
    )
  }
Enter fullscreen mode Exit fullscreen mode

Displaying slider content

People component will house the destructuring process, where the data id is the key attribute to access its properties. As shown below, the content of our slider is displayed via the variables assigned to the properties of the data. Due to the CSS properties of the slider, its content is stacked on one another. To rectify that, we have to create a variable named position with "nextSlide" as it’s default value. The variable then undergoes conditional rendering to adjust the position of the each slides.

//People.js
import React from 'react';
import { FaQuoteRight } from 'react-icons/fa';
import people from './data';

const People = ({id, image, name, title, quote, personIndex, index}) => {
 let position = "nextSlide";
 if(personIndex === index){
    position = 'activeSlide'
   }
 if(personIndex === index - 1 || (index === 0 && personIndex === people.length - 1)){
    position = 'lastSlide'
   }
  return(
   <article className={position} key={id}>
     <img src={image} alt={name} className="person-img" />
     <h4>{name}</h4>
     <p className="title">{title}</p>
     <p className="text">{quote}</p>
     <FaQuoteRight className="icon" />
   </article>
        );
    }

    export default People;
Enter fullscreen mode Exit fullscreen mode

Slider buttons

In the App component, the React icons β€” FiChevronLeft and FiChevronRight are imported to navigate back and forth through the sliders.

//App.js
<button className="prev" onClick={() => setIndex(index - 1)}>
<FiChevronLeft />
</button>
<button className="next" onClick={() => setIndex(index + 1)}>
<FiChevronRight />
</button>
Enter fullscreen mode Exit fullscreen mode

The code snippet above shows the buttons using an onClick event handler where the FiChevronRight button adds 1 to it’s index default value to switch to the next slider, while FiChevronLeft does the opposite.

Autoplay Feature

Hooks feature β€” useEffect

The React Hooks feature β€” useEffect, allows the execution of the autoplay feature possible. The slider is set to an interval of 5 seconds using a setInterval() function, where it automatically switches to the next slide without clicking the slider buttons. By using this, React will remember the function you passed, and call it later after performing the DOM updates. The useEffect feature also completes the functionality of the slider, where conditional rendering enables the slider to switch to the first item in the array once the last item is reached.

useEffect(() => {
  const lastIndex = people.length - 1
    if (index < 0) {
      setIndex(lastIndex)
      }
    if (index > lastIndex){
      setIndex(0)
      }
   }, [index, people])

useEffect(() => {
  let slider = setInterval(() => {
    setIndex(index + 1)
   }, 5000);
    return () => clearInterval(slider)
   }, [index])
Enter fullscreen mode Exit fullscreen mode

Video


This is a working demo of the slider in use.

Conclusion

Creating functional components does not have to be as complex as it once was. With React Hooks, we can get the state of the component so that it can be easily tested and reused. It also encapsulates logic without affecting the hierarchy of components.
To have an overview of the code base for this article, you can check it out on Github.

Top comments (0)

Timeless DEV post...

How to write a kickass README

Arguably the single most important piece of documentation for any open source project is the README. A good README not only informs people what the project does and who it is for but also how they use and contribute to it.

If you write a README without sufficient explanation of what your project does or how people can use it then it pretty much defeats the purpose of being open source as other developers are less likely to engage with or contribute towards it.