Build An Image Slider With React & ES6
Create an image slider in React they said, it will be fun they said…
Just kidding, it is fun, and I am going to show you how to do it. This tutorial omits certain aspects of functionality for sake of article length, but to make up for it, I have provided a Github repository with an advanced version of what I am building here, as well as a working version that you can use via Heroku here. The version I built on Github also uses Redux, so I encourage you to study the code…you might learn something new!
Structuring Our Image Slider
Step 1: Let’s get rocking and rolling. First, we need to plan the structure of our image slider. I have broken down what I think we need in the list below.
- Slider (Our top level parent component)
- Slide (Will contain the image/images)
- Arrows (Left and Right Arrows)
I will explain more about what each of these components does as we build them out. Let’s start out with some code for our Slider Component.
Slider is going to house all of the other components I listed above, and will also contain the logic that makes everything work together in tandem. In the example I built on Github, I style the slider class to be 100% width and 100% height of the viewport.
Creating The Slide Component
Step 2: Our next order of business for our image slider should be the creation of our Slide component, which we will create as a functional component. Slide is going to contain the actual image we want to display. CSS wise, Slide should match the width and height of the Slider Component.
Here is the basic setup for our Slide component.
In case you are wondering, if we have multiple images in our slider, we will tell our parent Slider component to render multiple instances of Slide. We have more work to do on this component, but its not really necessary at the moment, so let’s move on.
Create The Left and Right Arrows
Step 3: We are almost ready to hop back up to our parent Slider component and start writing some logic to make everything work. But before we do this, we should create our arrows. Let’s check out the code below and see what we have.
For the sake of cutting down on code embeds, I decided to show you both arrow components together in one file. Let’s pretend that each arrow is created within its own file though(which is good practice). Also, for those of you familiar with Font Awesome, you can see I am using that library to help create the arrows.
Grab Some Cool Images
Step 4: One last thing before we start working on Slider. This would be where you go online to find some great looking images, and save them to your project. I have already done this, and put my images into the dist folder of my repository.
Implementing Functionality In Slider
Step 5: We finally made it back to our parent Slider component, and we are ready to start building out the logic to make everything work. In order to do so, we need to import the child components we created into Slider. We can see what this looks like in the code snippet below.
This is definitely a good start, but this won’t do much for us, so let’ s start off by creating some click event listeners and hook them up to our arrows.
Setting Click Listeners On The Arrows
Step 6: I was thinking it might be a good idea to start off with something easy, as some of the other functionality contains concepts that could be confusing to some people. Therefore, instead of making the images work right now, we are going to take care of the arrows first.
In order to set the click event listeners on the arrows, we need to create two methods on our Slider component. One of the methods will handle the left arrow being clicked, and the other method will handle the right arrow being clicked.
(Just a forewarning, I will only be creating the logic to handle clicking the right arrow in this tutorial. As a challenge, I leave it up to you to figure out how you would implement the back arrow functionality.)
Let’s try to break down the functionality we need the right arrow to have.
- On right arrow click, increment some type of counter, and go to the next slide available. Also, if we have more than one image in our slider, and we have reached the end of the available images, hop back to the first image.
Notice how I mentioned the need for a “counter” of some sort. In order to move between different images in our slider, we need to keep track of what image we are currently viewing. This is a great opportunity to add some properties to our state object that will help us keep track of this slice of functionality.
For now, lets create the methods we talked about, and then pass them down as props to their corresponding component.
In order to have the ability to execute these functions inside the arrow components, we need to make sure that they are received properly inside the components themselves. This is one of the main concepts of React, and it is typically referred to as, “passing down props”.
Just know that you can name your prop attributes anything you want. I could have easily made my prop for the LeftArrow be,
React does not care what you name your props(The name of your prop is anything to the left of the = sign). All you need to be sure to do is call your prop in your child component by the name you assigned to it in the parent.
Lets take a look at how we can receive the reference to our methods via props below.
This looks great! Our arrows now have been connected to the methods in our parent Slider component, and can now be triggered when a user clicks on either of the arrows.
Adding Properties To Our State Object
Step 7: Now that we have the click events setup, we are going to veer of course just a tiny bit, and instead take some time to setup up the state we need. If the concept of state confuses you, really all it is is a way for you to keep track of things that are happening inside of your component(s).
With that being said, let’s think back to when I mentioned that we might want to implement some type of counter in our state to keep track of what image is currently being shown. There is really no easy way to conceptualize this until we create some type of data structure that knows about all of the images we want to show. Storing the name of the images we want to show in an array sounds like the perfect candidate in this situation.
So, I am going to propose that we create two properties on our state object:
- images (an array of image file names that sit in the dist folder)
- currentIndex (a number that tracks what index we are in the array)
Here is what that would look like:
We start currentIndex off at 0, because when the Slider component first renders to the screen, we want to show the first image.
Updating The Current Index In Our State Object
Now that we have that setup, we are going to add a few lines of code to our goToNextSlide method in order to update the currentIndex property in our state object.
We use the setState method provided to us by React to increment the currentIndex by 1 each time the right arrow is clicked. I highly recommend you read up on setState if you do not understand it.
Producing Multiple Instances of Slide Inside Slider
Using map on the array will produce three Slide components due to the fact that we have three image names in our images array. In order to make these images visible, we need to do some additional work inside of the Slide component.
Making Images Visible In Slide
In order to make these images visible, we are going to use the image name that we passed down to each instance of Slide inside of our map function in Slider. We will use the name of the image to set a background image on the Slide component.
Pretty easy right? Now lets hop back up to Slider and put the finishing touches on how we are going to display the images.
Using CSS Transforms To Show The Correct Image
Inside Slider we want to show only one image at a time. Currently, all three slides will be rendered to the screen and it will look like a garbled mess. In order to show just one image, I suggest we make use of a CSS transform property called translateX. Utilizing this will allow us to have the other images sitting off the screen and out of the view from the user. To make this work, we are going to wrap the slides that we rendered in a div, and dynamically translate that div each time we click the right arrow button.
When the Slider first renders on the screen, we want the default translateX value to be 0. In order to make this happen, we can set a new property into our state object to keep track of the translate value. Let’s see what I am talking about with some code.
Getting The Width Of The Slide And Setting A New Translate Value
Each time we click the right arrow we want to determine the width of the current slide in pixels, and subtract that amount from our current translate value in the state object. This will create a negative number, which we will use to update the translateValue property. Setting this new number into state will make the component re-render, and will thus make our slider wrapper div move to the left, revealing the next image that was hanging out off screen on the right side.
The easiest way to get the width of the current slide(that I can think of right now) is to create a new method in Slider that calculates the width of the current slide, and then returns it to us.
The code below is going to show the method being created, as well as some additional logic added to goToNextSlide. Check the comments inside of goToNextSlide to see what the added code does.
Getting the current width of the slide is crucial, as it determines exactly how many pixels we need to translate in order to get the next slide shown on the screen, without any overlap.
Summary Of Our React Image Slider
Congratulations! If you have made it this far through the tutorial, then you should now have a pretty good idea how to build your own React Image Slider. My example is far from perfect, but I hope it was able to provide you with some useful tips.
As I mentioned at the beginning of the article, please feel free to leave questions or comments if you have trouble understanding any of the code that I have included in the tutorial.
Please feel free to follow me on Twitter and Github.
Also, feel free to contact me via my website:
In terms of style when writing code, I aim for maintainability and elegance every time. While utilizing fancy newer…danzuzevich.com
We specialize in building custom web applications and CMS based websites. Our web application development tools include…graftonstudio.com