Reputation: 53
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
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
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
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