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).
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 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:
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.
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 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:
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 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:
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 to our handleSubmit
function:
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:
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:
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! :)
Top comments (6)
Very nice!
How could i implement an auto scrolling code?
Create an interval calling slideRight function and clearInterval as seen here w3schools.com/jsref/tryit.asp?file...
Having cors issues :/, is there a sandbox of this tutorial? Thank you!
Thank you. you just saved me a lot of headache
That is cool. Saved me lots of time. And i like styling things my own way.
what about making this slider work smothly ?