0

I am using useInterval in order to automatically pass pictures every 5 seconds, and I would like to know if there is a way to reset the delay when the "next" button is clicked. For instance, if I click the button after 3 seconds to pass to the second picture, then the third picture is passing to the next one after the remaining 2 seconds. The behavior that I would want is if I pass to the second picture by clicking on the button after, e.g. 3 seconds, the delay will restart to 5 seconds again.

This is a summary of my code:

const currentSlide = signal(0);
const intervalTime = 5000;

    function nextSlide() {
        if (currentSlide.value === slideLength-1) {
            return currentSlide.value = 0
        }
        else {
            return currentSlide.value++;
        }
    };

useInterval(() => { 
            nextSlide();
    }, intervalTime); 

It is very similar to what I found in this post, however, Jacki didn't post the solution.

Thanks in advance.

7
  • Remember that setInterval has clearInterval as counterpart. Commented Nov 9, 2023 at 4:11
  • Right, but for some reason it doesn't clear it after I click on the button. You can test this in this example codesandbox.io/s/ticker-liqo9?file=/src/index.js You will notice that if you increase the delay to e.g. 5000, and hit the restart button after 3s, you will notice the counter changes in less than 5s. Commented Nov 9, 2023 at 4:33
  • you're not actually doing anything when reset gets clicked though. Yes, you call setTick(0), but that's all that happens. What, in the code you wrote, makes you believe that it should have somehow triggered the function that you return in the deeply nested useEffect? (And please put that code in your post instead, so folks can meaningfully comment on it, after reducing it a little further to a minimal reproducible example) Commented Nov 9, 2023 at 15:19
  • 1
    not sure even that makes sense: just make the interval id itself a state value so you can use that? e.g. [timer, setTimer] = setState(-1) and a const reset = () => { clearInterval(timer); setTimer(setInterval(..., ...)); }? Why all the effects/callbacks/etc, that just makes things needlessly complicated? Commented Nov 9, 2023 at 15:48
  • 1
    It's easy to forget that React is still "just JS", where you end up writing way too much code because you're trying to only use React constructs =) Commented Nov 9, 2023 at 16:26

2 Answers 2

0

You can try this.

const currentSlide = signal(0);
const intervalTime = 5000;

function nextSlide() {
    if (currentSlide.value === slideLength-1) {
        return currentSlide.value = 0
    }
    else {
        return currentSlide.value++;
    }
    intervalTime = 5000; //to reset time after go next
};

useInterval(() => { 
      nextSlide();
}, intervalTime); 
Sign up to request clarification or add additional context in comments.

3 Comments

Tried this and it didn't work.
try make function to reset intervalTime and go next slide and link it with next button
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0

Answering..

in this example(codesandbox.io/..) You will notice that if you increase the delay to e.g. 5000, and hit the restart button after 3s, you will notice the counter changes in less than 5s.

You need to add a new state variable in your Ticker to control the delay. You should modify the useInterval to accept a delay that can be changed dynamically. This will allow you to adjust the delay based on certain conditions. Next, you need to adjust the delay based on the tick. If tick is greater than 540 and less than 900, you should set the delay example 5000(or 5 seconds). You can do this inside a useEffect that depends on the tick. Lastly, you need to reset the tick and the delay example 1000(or 1 second) when the warning or error message is clicked. You can do this inside the reset function.

Modified Ticker;

function Ticker({ onError }) {
 const [tick, setTick] = useState(0);
 const [delay, setDelay] = useState(1000);

 function reset() {
   setTick(0);
   setDelay(1000);
 }

 useEffect(() => {
   if (tick > 540 && tick < 900) {
     setDelay(5000);
   } else {
     setDelay(1000);
   }
 }, [tick]);

 useInterval(() => {
   console.log("useInterval");
   if (tick === -1) return;
   setTick(tick + 60);
 }, delay);

 if (tick >= 900) {
   onError();
 }

 return (
   <div>
     {tick > 540 && (
       <TickerAlert color="orange" message="Warning!" onClick={reset} />
     )}
     <b>{tick}</b>
   </div>
 );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.