Making a Simple Image Slider in React.js
Tags: react, beginners, javascript, tutorial
Published: 2020-09-15 01:18:55

Hello there! Today I’m going to walk through how to build a simple image slider in React without using any external packages. When I was working on my React project for Flatiron School, I wanted to include an image slider but didn’t know where to begin. Googling only led me to tutorials that involved installing external dependencies to your application. As someone who was new to React, I wanted to build an image slider from scratch. As a disclaimer, I will not be going over any styling in this tutorial, this is just meant to get you started with a React component that can cycle through images. If this is something you’re interested in, read on!

### **Setup**
Let's start off by creating a new React app. In your terminal/command line enter:
```
npx create-react-app image-slider
```
Then navigate to the image-slider directory and open it up in your favorite text editor (I use [VSCode](https://code.visualstudio.com/)).
```
cd image-slider
code . 
```
I also recommend running the app in a development server while you're coding so you can see the changes in the browser. You can do this by entering `npm start` in the terminal. This will open up a new tab or window in your browser with the url of `http://localhost:3000`. I also recommend installing the [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) extension if you're using Chrome as your browser.

Next, open up the **App.js** file located in the **src** folder. You should see this:
```react
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

```
To simplify things, let's remove a lot of the unneeded code for this tutorial and simply return a header of "Image Slider". I'll also refactor the **App** component to be an [arrow function] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions).
```react
import React from "react";
import "./App.css";

const App = () => {
  return (
    <div className="App">
      <h1>Image Slider</h1>
    </div>
  );
}

export default App;
```
Okay, now we're ready to start building our application.

### **App Component**
We will be building a simple app where the user can enter text into a search form and then the app will return an image slider where the user can click through images of the query. We will be grabbing images from the [Pixabay API](https://pixabay.com/api/docs/) in this tutorial, but feel free to use any image API you'd like. 

First, we will create a form with one text input field and a submit button:
```react
import React from "react";
import "./App.css";

const App = () => {
  return (
    <div className="App">
      <h1>Image Slider</h1>
      <form>
        <input type="text" />
        <input type="submit" value="Search" />
      </form>
    </div>
  );
};

export default App;
```
Next, we will use the `useState` [React hook] (https://reactjs.org/docs/hooks-intro.html) to manage the state of the input field. We will also set up the event listeners `onChange` to the input field and `onSubmit` to the form. See the comments below:
```react
import React, { useState } from "react";
import "./App.css";

const App = () => {
  const [query, setQuery] = useState(""); // declaring state variable "query" and "setQuery" method to update query state

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(query); // logging the value of query to test that the form is working
  };

  return (
    <div className="App">
      <h1>Image Slider</h1>

      <form onSubmit={handleSubmit}> {/* handleSubmit function will be called on form submit */}
        <input type="text" onChange={(e) => setQuery(e.target.value)} /> {/* onChange event listener will call setQuery to update query state variable */}
        <input type="submit" value="Search" />
      </form>
    </div>
  );
};

export default App;
```
We will be passing down the images from **App** to our **ImageSlider** component (not built yet) as a prop, so let's set up our images state with the `useState` hook and also add our fetch call to the [Pixabay API](https://pixabay.com/api/docs/) to our `handleSubmit` function: 
```react
import React, { useState } from "react"; // import useState hook
import "./App.css";

const App = () => {
  const [query, setQuery] = useState("");
  const [images, setImages] = useState([]); // declare state variable "images" to an empty array and "setImages" method to update images state

  const handleSubmit = (e) => {
    e.preventDefault();
    fetch(
      `https://pixabay.com/api/?key=[api-key]&q=${query}`
    )  // fetch to API by passing in query state
      .then((response) => response.json())
      .then(({ hits }) => hits.map(({ webformatURL }) => webformatURL)) // use object destructuring to grab image urls from json response
      .then(setImages); // call setImages to update images state with image urls
  };

  return (
    <div className="App">
      <h1>Image Slider</h1>

      <form onSubmit={handleSubmit}>
        <input type="text" onChange={(e) => setQuery(e.target.value)} />
        <input type="submit" value="Search" />
      </form>
    {/* Will import ImageSlider component here */}
    </div>
  );
};

export default App;

```
Now that our App component is set up, we can now build our **ImageSlider** component which will be imported into **App**.

### **ImageSlider Component**
In the **src** folder, lets create a new folder called **components**, and in it create a new file called **ImageSlider.js**. This is where we will be creating our image slider.

Our **ImageSlider** component takes in images (an array of image urls) from **App** as a prop and returns the first image in the array along with "left" and "right" buttons. When the user clicks on a button, our **ImageSlider** will return either the next or previous image in the array, thus creating the ability to cycle through images:
```react
import React, { useState } from "react";

const ImageSlider = ({ images }) => { // takes in images as props
  const [index, setIndex] = useState(0); // create state to keep track of images index, set the default index to 0

  const slideRight = () => {
    setIndex((index + 1) % images.length); // increases index by 1
  };

  const slideLeft = () => {
    const nextIndex = index - 1;
    if (nextIndex < 0) {
      setIndex(images.length - 1); // returns last index of images array if index is less than 0
    } else {
      setIndex(nextIndex);
    }
  };

  return (
    images.length > 0 && (
      <div>
        <button onClick={slideLeft}>{"<"}</button>
        <img src={images[index]} alt={index} />
        <button onClick={slideRight}>{">"}</button>
      </div>
    )
  );
};

export default ImageSlider;

```
Finally, the last thing we have to do is simply import our **ImageSlider** into **App**:
```react
import React, { useState } from "react";
import ImageSlider from "./components/ImageSlider"; // import ImageSlider
import "./App.css";

const App = () => {
  const [query, setQuery] = useState("");
  const [images, setImages] = useState([]);

  const handleSubmit = (e) => {
    e.preventDefault();
    fetch(
      `https://pixabay.com/api/?key=[api-key]&q=${query}`
    )
      .then((response) => response.json())
      .then(({ hits }) => hits.map(({ webformatURL }) => webformatURL))
      .then(setImages);
  };

  return (
    <div className="App">
      <h1>Image Slider</h1>

      <form onSubmit={handleSubmit}>
        <input type="text" onChange={(e) => setQuery(e.target.value)} />
        <input type="submit" value="Search" />
      </form>

      <ImageSlider images={images} /> {/* return ImageSlider and pass images as a prop */}
    </div>
  );
};

export default App;

```
Congrats, you've successfully created an image slider in React from scratch! Now that you have a functioning image slider, the next thing to do would be to add your own unique styles to it (CSS transitions, animations, custom icons, etc). I hope you found this tutorial helpful in some way. Happy coding! :)