Karthikeyan M
Karthikeyan M

Reputation: 106

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

Upvotes: 0

Views: 1026

Answers (2)

Javi Villar
Javi Villar

Reputation: 117

For me, the easiest way to solve this behavior was set the interval as a Ref:

import { useRef } from 'react';

// Initialize the interval ref
const interval = useRef();

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

// Remove the interval
function onclicks() {
  clearInterval(interval.current);
  setImage(blanked);
}

Using this hook, the component will not re-render when you change the value remove/change the interval.

Upvotes: 1

pilchard
pilchard

Reputation: 12928

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);
  }
}

Upvotes: 1

Related Questions