Skip to content

JavaScript On-click Function to start and stop Intervals

I have two onclick functions that performing start and stop functions using socket when i click start it start requesting images from server(i am using intervals) when i click stop the server is stopped but the request keep coming to the server. the intervals seems not stopped after clicking kindly review my code

Code:

  var interval;
  
  function onclick() {
    interval = setInterval(() => {
      socket.emit("get_image", "Click");
      socket.on('send_image', (message) => {
        setImage(message.image); 
      });
    }, 350)
  }

  function onclicks() {
    clearInterval(interval);
    setImage(blanked);

  }

I have tried to add clearInterval function but it seems not working

Answer

Variables declared at the top level of a component are redeclared on each render (here every time you call setImage()) so interval is undefined by the time onclicks() is called.

In order to maintain the value through renders you need to either use state (useState) or a ref (useRef) which won’t lose it’s value. In this case, since you don’t want renders attached to the value of interval a ref is more appropriate. useRef() returns an object with a current property in which your value will be stored.

const interval = React.useRef(null);
  
function onclick() {
  interval.current = setInterval(() => {
    socket.emit("get_image", "Click");
    socket.on('send_image', (message) => {
      setImage(message.image); 
    });
  }, 350);
}

function onclicks() {
  clearInterval(interval.current);
  interval.current = null; // reset the ref
  setImage(blanked);
}

You probably also want to avoid setting multiple intervals. You may already be doing so, but if not you can check if interval is null or not before setting a new one.

const interval = React.useRef(null);
  
function onclick() {
  if (interval.current === null) { // only set new interval if interval ref is null
    interval.current = setInterval(() => {
      socket.emit("get_image", "Click");
      socket.on('send_image', (message) => {
        setImage(message.image); 
      });
    }, 350);
  }
}