I have a content carousel on a project in NextJS. The carousel is based on Snap Scroll CSS and the next and prev buttons have been added so that you can control scrolling from the buttons.
const carouselRef = useRef(null)
const carouselItemRef = useRef(null)
const [currentIndex, setCurrentIndex] = useState(0)
const scrollToRight = (e) => {
e.preventDefault()
carouselRef.current.scrollBy({
left: carouselItemRef.current.clientWidth,
top: 0,
behavior: 'smooth',
})
setCurrentIndex(prevState => prevState + 1)
}
const scrollToLeft = (e) => {
e.preventDefault()
carouselRef.current.scrollBy({
left: -carouselItemRef.current.clientWidth,
top: 0,
behavior: 'smooth',
})
setCurrentIndex(prevState => prevState - 1)
}
The buttons perfectly scroll through the slides in the carousel. And the ‘show’ class is added when needed, according to the code below. But I would like this class to be removed at the moment of scrolling left and right to the end, which would allow me to change its appearance when there are no slides to scroll in one direction or another. And the class is deleted, but 1 click later.
<div>
<button onClick={scrollToLeft} className={`${currentIndex > 0 ? 'show' : ''}`}><</button>
<button onClick={scrollToRight} className={`${currentIndex < 4 ? 'show' : ''}`}>></button>
</div>
That is, if I have five slides – two on the screen, I scroll the carousel to the right, in theory I need to click 4 times to remove the ‘show’ class on the button, but in fact only after the fifth click, the class is deleted.
What needs to be done to make everything work as it should? Below I have the full component code
import { useState, useRef } from 'react';
import styles from '@/styles/home/reviews.module.css'
export default function Reviews () {
const items = [
{ title: 'title1', name: 'name1', content: 'content1' },
{ title: 'title1', name: 'name1', content: 'content1' },
{ title: 'title1', name: 'name1', content: 'content1' },
{ title: 'title1', name: 'name1', content: 'content1' },
{ title: 'title1', name: 'name1', content: 'content1' },
];
const carouselRef = useRef(null)
const carouselItemRef = useRef(null)
const [currentIndex, setCurrentIndex] = useState(0)
const scrollToRight = (e) => {
e.preventDefault()
carouselRef.current.scrollBy({
left: carouselItemRef.current.clientWidth,
top: 0,
behavior: 'smooth',
})
setCurrentIndex(prevState => prevState + 1)
}
const scrollToLeft = (e) => {
e.preventDefault()
carouselRef.current.scrollBy({
left: -carouselItemRef.current.clientWidth,
top: 0,
behavior: 'smooth',
})
setCurrentIndex(prevState => prevState - 1)
}
return (
<section className={styles.reviews}>
<div className="wrapperScroll">
<h2 className="sectionTitle">reviews</h2>
<div>
<button onClick={scrollToLeft} className={`${currentIndex > 0 ? 'show' : ''}`}><</button>
<button onClick={scrollToRight} className={`${currentIndex < 4 ? 'show' : ''}`}>></button>
</div>
<div className={styles.reviewsInner} ref={carouselRef}>
{items.map((n, i) => (
<div className={styles.reviewsItem} key={i} ref={carouselItemRef} data-index={`data-${i}`}>
<h3>{n.title}</h3>
<p>{n.content}</p>
<p>{n.name}</p>
</div>
))}
</div>
</div>
</section>
);
}