I have a few testimonials that users can scroll through. On mobile, I have a function that detects a swipe and changes the index of an array based on the direction. It works and cycles through correctly, but if I scroll backwards when the index=0, I crash the app. How can I ensure the array cycles back to the end of array.length?
Here is the section I'm having trouble with:
const [touchPosition, setTouchPosition] = useState(null)
const handleTouchStart = (e) => {
const touchDown = e.touches[0].clientX
setTouchPosition(touchDown)
}
const handleTouchMove = (e) => {
const touchDown = touchPosition
if(touchDown === null) {
return
}
const currentTouch = e.touches[0].clientX
const diff = touchDown - currentTouch
if (diff > 5) {
setIdx((prevIndex) =>
prevIndex === testimonials.length - 1 ? 0 : prevIndex 1
)
}
if (diff < -5) {
setIdx((prevIndex) =>
prevIndex === testimonials.length - 1 ? 0 : prevIndex - 1
)
}
setTouchPosition(null)
}
And here is the component:
const Testimonials = props =>{
const testimonials = [
{
name: 'Name1',
position: 'Title1',
photo: require('./img/chrisphoto.png'),
text:
'Body1'
},
{
name: 'Name2',
position: 'Title2',
photo: require('./img/jillphoto.png'),
text:
'Body2'
},
{
name: 'Name3',
position: 'Title3',
photo: require('./img/mikephoto.png'),
text:
'Body3'
},
];
const [idx, setIdx] = useState(0);
let name = testimonials[idx].name;
let position= testimonials[idx].position;
let photo= testimonials[idx].photo;
let text = testimonials[idx].text;
const [touchPosition, setTouchPosition] = useState(null)
const handleTouchStart = (e) => {
const touchDown = e.touches[0].clientX
setTouchPosition(touchDown)
}
const handleTouchMove = (e) => {
const touchDown = touchPosition
if(touchDown === null) {
return
}
const currentTouch = e.touches[0].clientX
const diff = touchDown - currentTouch
if (diff > 5) {
setIdx((prevIndex) =>
prevIndex === testimonials.length - 1 ? 0 : prevIndex 1
)
}
if (diff < -5) {
setIdx((prevIndex) =>
prevIndex === testimonials.length - 1 ? 0 : prevIndex - 1
)
}
setTouchPosition(null)
}
useEffect(() => {
const interval = setInterval(
() => setIdx(idx => (idx 1) % testimonials.length), 120000,
);
return () => {
clearInterval(interval);
};
}, []);
return (
<div className="testimonials_main">
<div className="home-testimonial-container"
onTouchStart={handleTouchStart} onTouchMove={handleTouchMove}
>
<img className="quotes" src={quotes}/>
<img className="quotes2" src={quotes2}/>
<div className='testimonial-entry'>
<button className="next-testimonial" onClick={() => {
setIdx(idx => (idx 1) % testimonials.length);
}}style={{
backgroundImage: `url(${nextarrow})`,
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center',
backgroundSize: '10px'}}></button>
<button className="last-testimonial" onClick={() => {
setIdx(idx => (idx - 1) % testimonials.length);
}}style={{
backgroundImage: `url(${lastarrow})`,
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center',
backgroundSize: '10px'}}></button>
<img className='testimonial-photo'
src={photo}
></img>
<div className='testimonial-text'>
<h3 className='testimonial-name2' >{name}</h3></div>
<div className='testimonial-text2'><h3 className='testimonial-title2' >{position}</h3></div>
<div className='testimonial-body-container'><h3 className='testimonial-body2' style={{fontStyle:"italic"}}>{text}</h3>
</div>
</div>
<div className="testimonialDots">
{testimonials.map((_, index) => (
<div key={index} className={`testimonialDot${index === idx ? " active" : ""}`} onClick={() => {
setIdx(index);
}}></div>
))}
</div>
</div>
</div>
);
}
export default Testimonials;
CodePudding user response:
if (diff < -5) {
setIdx((prevIndex) =>
prevIndex === 0 ? 0 : prevIndex - 1
)
}