HOODINI
HOODINI

Reputation: 53

React Native: Call function when a specific state changes

Is it possible to call a function I define whenever a specific state changes?

For example:

function Component(props) {
   const [timerOn, setTimerOn] = useState(false);
   function startTimer() {
      setTimerOn(true);
      setTimeout(() => setTimerOn(false), 1000)
   }
   startTimer();
}

I need to call startTimer whenever setTimerOn(false) is called. How do I do that without calling startTimer every time the screen is rendered?

Upvotes: 3

Views: 8483

Answers (3)

tundeJS
tundeJS

Reputation: 41

Since you are already using hooks. The useEffect hook will come to your rescue in this scenerio. More about it here

Upvotes: 2

Lim Jing Rong
Lim Jing Rong

Reputation: 426

useEffect is perfect here since you're already using React hooks. As stated in the official documentation -

The Effect Hook lets you perform side effects in function components

So in your case,

function Component(props) {
   const [timerOn, setTimerOn] = useState(false);
   function startTimer() {
      setTimerOn(true);
      setTimeout(1000, () => setTimerOn(false))
   }

   // This code is for it to run for the first time when your component mounts. 
   // Think of it as the previous componentDidMount function
   useEffect(() => {
     startTimer();
   }, []);

   // This code is for it to run whenever your variable, timerOn, changes
   useEffect(() => {
     if (!timerOn) {
       startTimer();
     }
   }, [timerOn]); // The second parameters are the variables this useEffect is listening to for changes.
}

Upvotes: 8

MaCadiz
MaCadiz

Reputation: 1817

You can use the hook useEffect, this hook lets you execute code when any of the values inside the dependency array changes. You can use it like this

useEffect(()=> {
  doSomethingWhenFooChanges();
},[foo]);

Edit to enrich answer:

You can do something like this:

function Component(props) {
  const [timerOn, setTimerOn] = useState(false);
  function startTimer() {
     setTimerOn(true);
  }

  //Declaring timer variable
  let timer;

  useEffect(()=> {
    if(!timerOn) {
      timer = setTimeout(() => setTimerOn(false), 1000);
      startTimer();
    } else {
       //To prevent memory leaks you must clear the timer
      clearTimeout(timer);
    }
  }, [timerOn]);
}

In any case, I can't think of an scenario that you need to restart a timer when you can use setInterval. That function executes a function every 'n' seconds. And it's used like:

setInterval(()=> {
  myFunctionToBeExecutedEvery1000ms();
}, 1000);

Regards

Upvotes: 2

Related Questions