DEV Community

Nabaraj saha
Nabaraj saha

Posted on

Build React Carousel - Part3

This is the last and final part of this series

Will explain how to implement the animation and timer. For reference I am adding the final coding part again.

We are using state which is one of the key concept of React. It is basically an object of this file, which holds various key-value pairs. It is initialized in constructor by statement like this.state = { };

But when we need to change it, we can do only by statement like this.setState({ });

In React whenever the state is changed the some of the component life cycle methods will get call like componentDidMount and render method

Now let go through the flow to understand how state and props works. We are using ES6 constructor, which will run first when the "Carousel" is called first from App . Inside constructor, we are setting our initial state object by
this.state = {
transform: 0,
currentSlide: 0,
totalSlide: 0,
autoScrollTimer: this.props.autoScrollTimer || 5000,
showLeftArrow: false,
showRightArrow: true
};

this.carouselTimer = "";

which set a key-value pair. I also initialised one variable to store the timer so that it will be available through the component and we can clear the timer when is required.

There are some methods or handler I am using

clearTimer =clear the timer on mouse enter
startTimer = start the carousel animation
showArrow = to control the display arrow
slideLeft = animate slider to left
slideRight = animate slider to right
startCarousel = start the timer after pause
arrowMaker = return arrow element

After the constructor is run, some react life cycle methods will run like componentDidMount and render(). Inside componentDidMount the code is

let carousel = this.carousel.getBoundingClientRect();
let containerWidth = carousel.width;
let carouselWidth =
this.props.sliderType === "fullScreen"
? containerWidth * this.props.children.length
: this.carouselInnerContent.getBoundingClientRect().width;
let totalSlide = Math.ceil(carouselWidth / containerWidth);
this.setState(
{
totalSlide
},
() => {
this.startTimer();
}
);

we are taking carousel width and carouselInnerContent width as we are using grid carousel the slide count is depend on totalSlide = Math.ceil(carouselWidth / containerWidth);

and we are storing totalSlide in the state. After doing setState I passed start timer as a callback. As setState is an asynchronous call sometimes the updates state may not reflect in next line.

inside startTimer will check if autoScroll true is passed or not and based on that will run setInterval

if (vm.props.autoScroll) {
this.carouselTimer = setInterval(() => {

and the time duration will be vm.state.autoScrollTimer as declared before.

Again will check the totalSlide inside setInterval. It is good to check in every interval so that if we resize the browser window it will reset the width and total slide as well and no need to add any observer.

I am maintaining another state that is transform it will add the css translateX value each interval or each time we click on arrow. For more information about translateX check here.

I am checking if currentSlide * containerWidth + containerWidth > carouselWidth then will not slide full only remaining length.

Also after a successful updating of transform, totalSlide and currentSlide(which is holding the present slide) will call the showArrow method in callback so that it will hide and show arrow.

showArrow = currentSlide => {
if (currentSlide === 0) {
this.setState({
showLeftArrow: false
});
} else {
this.setState({
showLeftArrow: true
});
}
if (currentSlide === this.state.totalSlide - 1) {
this.setState({
showRightArrow: false
});
} else {
this.setState({
showRightArrow: true
});
}
};

showArrow is simple only checking currentSlide and hide and show arrow.

the slideLeft and slideRight method also almost same like startTimer only controlling the direction based on right and left and update the transform state.

That's all the functionality of carousel. Hope it will help to understand the code.

Thanks for go through this article. I have created a node package for the same So that directly we can use that. Please check here

Top comments (3)

Collapse
 
dance2die profile image
Sung M. Kim

Thank you for the awesome series, Nabaraj~

And may I request to update code formatting for the last code snippet?

(Please refer to the Editor Guide)

Collapse
 
nabaraj profile image
Nabaraj saha

Thanks Sung M.Kim for your feedback this is my first post don't have much experience in writing and using editor. I will fix that formatting part.

Collapse
 
dance2die profile image
Sung M. Kim

No worries, mate.

It takes some time to get used to the formatting.

I also use gists in my posts, so you are fine to use gists if you want πŸ˜‰