skip to Main Content

I have a problem with the automatic content change. After 7 seconds it should change automatically by 1 (and so it works). The problem is that when the user clicks on the first card, after the carousel automatically goes to the second card, the interval, which is already running, completes its cycle and increases the index, causing the carousel to jump to the third card, not the the second etc.

  useEffect(() => {
    intervalRef.current = setInterval(() => {
      const nextIndex = (activeIndex + 1) % expertise.length;
      setActiveIndex(nextIndex);
      ;
    }, 7000);
  
    return () => clearInterval(intervalRef.current);
  }, [activeIndex]);
  
  const handleCardClick = (index) => {
    setActiveIndex(index);
    clearInterval(intervalRef.current);
  };

I would like to see it work this way. If the content automatically changes to, for example, the fourth card, and the user then changes to the first, then after 7 seconds it should change to the second, and so on.

3

Answers


  1.   // This function both initializes, and then at any time resets, the
      // interval that causes the periodic setting of cards
      const resetInterval = ()=>{
        if(intervalRef.current){
          clearInterval(intervalRef.current);
        }
        intervalRef.current = setInterval(() => {
          const nextIndex = (activeIndex + 1) % expertise.length;
          setActiveIndex(nextIndex);
          ;
        }, 7000);
      }
    
      // whenever the currently active index changes, 
      // we clear the exististing interval and set a new one
      useEffect(() => {
        resetInterval()
      
        return () => clearInterval(intervalRef.current);
      }, [activeIndex]);
      
      // whenever the user interacts we clear the existing interval and
      // set a new one.
      const handleCardClick = (index) => {
        setActiveIndex(index);
        resetInterval()
      };
    

    Whenever a user clicks a card, you can clear the interval and start it again. That way it will always be a full 7 seconds between every card change. I think that was your problem?

    The other interpretation i can see of your question is that you are having trouble synchronizing the active index variable. I don’t think that you should have an issue with the code above, I think it should stay synced, but if you are having trouble you could start using a ref to track the current index:

    If you do this, the interval handler will always know what the active index is.

      const currentIndexRef = React.useRef(activeIndex)
      currentIndexRef.current = activeIndex;
    
    
      const resetInterval = ()=>{
        if(intervalRef.current){
          clearInterval(intervalRef.current);
        }
        intervalRef.current = setInterval(() => {
          const nextIndex = (currentIndexRef.current + 1) % expertise.length;
          setActiveIndex(nextIndex);
          ;
        }, 7000);
      }
    
      useEffect(() => {
        resetInterval()
      
        return () => clearInterval(intervalRef.current);
      }, [activeIndex]);
      
      const handleCardClick = (index) => {
        setActiveIndex(index);
        resetInterval()
      };
    
    Login or Signup to reply.
  2. You need to reset the interval whenever the user manually changes the card. This can be done by clearing the existing interval and setting a new one each time the active index changes, whether automatically or manually

    useEffect(() => {
      // Function to start the interval
      const startInterval = () => {
        intervalRef.current = setInterval(() => {
          const nextIndex = (activeIndex + 1) % expertise.length;
          setActiveIndex(nextIndex);
        }, 7000);
      };
    
      // Start the interval
      startInterval();
    
      // Clear interval on cleanup
      return () => clearInterval(intervalRef.current);
    }, [activeIndex]); // Dependency on activeIndex
    
    const handleCardClick = (index) => {
      setActiveIndex(index);
      // Clear and restart the interval whenever a card is clicked
      clearInterval(intervalRef.current);
      startInterval(); // You need to define this function inside the useEffect
    };
    
    Login or Signup to reply.
  3. Simply use the functional form of setState so your captured activeIndex reference isn’t stale.

    setActiveIndex(activeIndex => (activeIndex + 1) % expertise.length);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search