Weekly Webtips
Published in

Weekly Webtips

Image Slider using React Slick

Image Slider with React Slick

React slick is a great carousel component for creating an image slider or carousel-like UI components. But sometimes we need some manual control over the default features that the library provides.

Last time when I worked with the library I tried to create an image slider with some extra features that React Slick doesn’t provide. I need to create a slider where I will conditionally show each slider navigator on the left side and right side.

But unfortunately, there were no such features in React Slick to conditionally show just one arrow navigator.

Today I am going to share my experience of customizing the React Slick component with custom arrow navigators.

Installation

Installing React Slick

yarn add react-slick

I am using typescript for the demonstration so I need to add type definition.

yarn add @types/react-slick

More info about the React Slick

I am also using Emotion for styling the components but that is totally up to you.

Usage

Initial Image Slider component

Sider Arrow component

For simplicity, I will add the React Slick styles directly in Style.css

// Style.css
@import url('https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css');
@import url('https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css');

This will render a simple image slider.

Click Events of Slider Arrow

Now we have to control the onClickevents of the SliderArrow. The functionality will be going to the next or previous image by clicking those SliderArrow.

If we go to the definition of Slider component (By Command + Click) that we are using in the ImageSlider component then we will see that it extends a React component with some additional methods.

We need to access the slickNext and slickPrev methods.

To access those methods we will use useRef hooks from react. We will set a reference in the Slider component and then we will be able to access all the public properties and methods from Slider component by using that reference.

const sliderRef = useRef<Slider>(null);
..........
return (
<SliderWrapper>
<SliderArrow type="prev" onClick={() => sliderRef.current.slickPrev()} />}
.................
<SliderArrow type="next" onClick={() => sliderRef.current.slickNext()} />}
</SliderWrapper>
);

Now if you click on the Slider Arrow’s then you can traverse the images using those two buttons.

Advanced Features

Now it’s time to make the slider more intelligent.

If we are are at the beginning of the slider then there is no point to show the previous arrow and if we are at the end of the slider then we should also not show the next arrow.

To control the visibility we need to know the current slide position. We can get that by afterChange option from Slider settings object.

const settings: Settings = {
.......,
afterChange: (currentSlide: number) => handleChangeSlide(currentSlide)
}

We will also declare two states for controlling the visibility of arrow buttons. One more state to set the max number of slides to show.

const [showRightArrow, setShowRightArrow] = useState<boolean>(false);
const [showLeftArrow, setShowLeftArrow] = useState<boolean>(false);
const [maxNumberOfCardsToShow, setMaxNumberOfCardsToShow] = useState<number>(0);

The change slide handler

const handleChangeSlide = (currentSlide: number) => {
const leftArrowVisible = currentSlide !== 0;
const rightArrowVisible = currentSlide <= data.length - maxNumberOfCardsToShow;
setShowLeftArrow(leftArrowVisible);
setShowRightArrow(rightArrowVisible);
};

The above handler code will be executed after each slide change.

Now we will conditionally render the arrow buttons.

{showLeftArrow && ( <SliderArrow type="prev" onClick={() => sliderRef.current.slickPrev()} />)}
........
{showRightArrow && ( <SliderArrow type="next" onClick={() => sliderRef.current.slickNext()} />)}

Now when the component rendered first we have to check the maximum number of images that we can show in one frame and also we have to check whether we will show the right arrow or not.

So we will set another div referenceSliderWrapper to know the width of the wrapper.

const sliderWrapperRef = useRef<HTMLDivElement>(null);...<SliderWrapper ref={sliderWrapperRef}>

We will perform all the calculations inside useEffect hook.

useEffect(() => {
const wrapperWidth = sliderWrapperRef.current.clientWidth || 0;

const maxNumberOfCards = Math.ceil(wrapperWidth / EACH_SLIDE_WIDTH);

setMaxNumberOfCardsToShow(maxNumberOfCards);
setShowRightArrow(data.length > maxNumberOfCards);
}, []);

I declared the EACH_SLIDE_WIDTH as a constant on the top of the component. You can also get this value as props.

const EACH_SLIDE_WIDTH = 176;

That’s all! Now you have a full-featured image slider with all of the controls on your hand.

I have done some more refactoring and style improvements. Here is the link to the complete code.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ashraful Islam

Ashraful Islam

54 Followers

Software Engineer | Javascript Developer | React | React Native | Angular | NodeJS