Reputation: 1375
I am using react-slick and I have my own customised arrows. This Slider is NOT an infinite loop and I would like to hide the arrows at the start and end of the loop. So basically at start PrevArrow should be hidden and at the end the NextArrow should be hidden. Which I am trying to set hidden class name depending on state changes. However the class name is not changing although the state is changing correctly. Do you know what's the problem with this code? and how to get it work?
Below is my setting for Slider and the component which renders Slider.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Slider from 'react-slick';
import Arrow from '../slider/Arrow';
export default class CityCarousel extends Component {
constructor(props) {
super(props);
this.state = {
displayLeftArrow: true,
displayRightArrow: true
};
this.slidesToShow = 5;
this.sliderSetting = {
dots: false,
arrows: true,
infinite: false,
initialSlide: 0,
slidesToShow: this.slidesToShow,
slidesToScroll: 1,
speed: 500,
rows: 0,
nextArrow: <Arrow
styleClassName={`city-carousel__right ${
this.state.displayRightArrow ? '' : 'city-carousel__right--hide'
}`}
direction="right"
clickHandler={this.clickHandler}
/>,
prevArrow: <Arrow
styleClassName={`city-carousel__left ${
this.state.displayLeftArrow ? '' : 'city-carousel__left--hide'
}`}
direction="left"
clickHandler={this.clickHandler}
/>,
afterChange: currentSlide => this.setArrowDisplay(currentSlide)
};
}
clickHandler = direction => {
if (direction === 'left') {
this.slider.slickPrev();
} else if (direction === 'right') {
this.slider.slickNext();
}
};
setArrowDisplay = currentSlide => {
const { cityList } = this.props;
const displayLeftArrow = currentSlide !== 0;
const displayRightArrow = currentSlide !== cityList.length - this.slidesToShow;
this.setState({ displayRightArrow, displayLeftArrow });
};
render() {
const { cityList, tours } = this.props;
return (
<div>
<div className="city-selection">
<Slider
ref={c => this.slider = c }
{...this.sliderSetting}
>
{cityList.length > 0 ? this.renderCityList() : null}
</Slider>
</div>
</div>
);
}
}
Here is also code for Arrow component
import React from 'react';
import PropTypes from 'prop-types';
const Arrow = ({ styleClassName, direction, clickHandler }) => {
return(
<div
className={`slick-arrow--${direction} slider-arrow--${direction} ${styleClassName}`}
onClick={e => clickHandler(direction)}
/>
)};
Arrow.propTypes = {
styleClassName: PropTypes.string,
direction: PropTypes.string,
clickHandler: PropTypes.func
};
export default Arrow;
Upvotes: 6
Views: 11068
Reputation: 1067
In 2022, we have boolean arrows, just declare it false in settings.
const settings = {
...,
arrows: false,
};
Upvotes: 3
Reputation: 21
Pass the current slide prop to the component and do a check for the slide you want to trigger hiding the arrow:
function SamplePrevArrow(props) {
const { currentSlide, className, onClick } = props;
if (currentSlide === 0) {
return false;
} else {
return <div className={className} onClick={onClick} />;
}
}
Upvotes: 2
Reputation: 1263
If you want the best manual controls over the arrow then use a custom arrow.
Set the onClick
handler of that component by using a ref
in the main Slider
component.
const sliderRef = useRef<Slider>(null);
<Slider {...settings} ref={sliderRef}>
Use states to conditionally show or hide arrows.
I wrote a blog post which covers the workflow to achieve similar kind of functionalities you want. You can have a look there.
https://medium.com/@imasharaful/image-slider-with-react-slick-d54a049f043
Upvotes: 0
Reputation: 6639
It seems react-slick
is not re-rendering <Arrow />
with new props, and it's always with first initialized props setting.
I think the solution is to get <Arrow />
out of slider like this:
<div className="city-selection">
<Arrow
styleClassName={`city-carousel__right ${
this.state.displayRightArrow ? '' : 'city-carousel__right--hide'
}`}
direction="right"
clickHandler={this.clickHandler}
/>
<Arrow
styleClassName={`city-carousel__left ${
this.state.displayLeftArrow ? '' : 'city-carousel__left--hide'
}`}
direction="left"
clickHandler={this.clickHandler}
/>
<Slider
{/* list of items*/}
</Slider>
</div>
you can see how it's working in here
Upvotes: 2
Reputation: 13966
In your this.sliderSettings
set nextArrow
& prevArrow
for your Arrow component do something like this
<Arrow
styleClassName={'YOUR_CLASSES_HERE'}
direction="right"
clickHandler={this.clickHandler}
isHidden={this.state.isHidden}
/>
Where this.state.isHidden
is the state variable where you are trying toggle the arrows.
Then in your Arrow
component do something like this.
const Arrow = ({ styleClassName, direction, clickHandler, isHidden }) => {
return (
<div
className={`slick-arrow--${direction} slider-arrow--${direction}
${styleClassName}`}
style={{ display: isHidden: 'none': 'block' }}
onClick={e => clickHandler(direction)}
/>
)
};
Upvotes: 0