Michael
Michael

Reputation: 439

How to call setInterval only once

I have a counter that should update count by 1 each seconds the user inputed.

In my code I have 2 logs, the 1st one when the interval start, and the seconds one when I need to clearInterval.

export default function App() {
  const [count, setCount] = useState(0);
  const [ms, setMS] = useState(1000);

  useEffect(() => {
    const interval = setInterval(() => {
      console.log("Start inteval");
      setCount((prevCount) => prevCount + 1);
    }, ms);

    return () => {
      console.log("Clear interval");
      clearInterval(interval);
    };
  }, [ms]);

  return (
    <div className="App">
      <input value={ms} onChange={(e) => setMS(e.target.value)}></input>
      <h1>{count}</h1>
    </div>
  );
}

The problem is, that the line console.log("Start inteval"); is colled every time when I update the count.

For example if the time for delay is 1 seconds , so the console.log("Start inteval"); will called every second.

I need to call it only once, is this possible ? But the counter should run...

Upvotes: 0

Views: 221

Answers (3)

Ankit Acharya
Ankit Acharya

Reputation: 36

you can do like this.

const App=()=> {
  const [count, setCount] = useState(0);
  const [ms, setMS] = useState(1000);
  const [prev ,setPrev] = useState(ms)

  const changeMs = (e) => {
    setMS(e)
    setPrev(e)
  }

  const runInterval = () => {
    setPrev("stop")

    if(prev===ms)
    {
      console.log("start Interval")
    }
    setCount((prevCount) => prevCount + 1);

  }
  useEffect(() => {
    const interval = setInterval(runInterval, ms);
    return () => {
      console.log("clear interval")
      clearInterval(interval);
    };
  }, [ms,prev]);

  return (
    <div className="App">
      <input value={ms} onChange={(e) => changeMs(e.target.value)}></input>
      <h1>{count}</h1>
    </div>
  );
}

This will run start interval in console only once after ms is changed

Upvotes: 0

Dibash sapkota
Dibash sapkota

Reputation: 19

You can use setTimeout to run code only once at delay

setTimeout(function(){ alert("Hello"); }, 3000);

you can use set interval and reset timer

let timer= setInterval(function() {
  console.log('timer');
  clearTimeout(remaingTime);
}, 1000);

Upvotes: 1

Isaac Vega
Isaac Vega

Reputation: 330

That can be solved with a flag. The code turns like this:

default function App() {
  const [count, setCount] = useState(0);
  const [ms, setMS] = useState(1000);
  let first = true;

  useEffect(() => {
    const interval = setInterval(() => {
      first && console.log("Start inteval");
      first = false;
      setCount((prevCount) => prevCount + 1);
    }, ms);

    return () => {
      console.log("Clear interval");
      clearInterval(interval);
    };
  }, [ms]);

  return (
    <div className="App">
      <input value={ms} onChange={(e) => setMS(e.target.value)}></input>
      <h1>{count}</h1>
    </div>
  );
}

Upvotes: 0

Related Questions