How can I prevent my React app from crashing when I scroll to a non-indexed value in my array?

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;

>Solution :

if (diff < -5) {
  setIdx((prevIndex) =>
  prevIndex === 0 ? 0 : prevIndex - 1
)
}

Leave a Reply