Something that I am struggling to understand in a react app is the correct use of setInterval, when i want to have an option that just exists early (but keeps the interval running) where that option is some piece of state within the app.
I have the following useEffect
:
useEffect(() => {
if (wallet.publicKey && intervalref.current === null) {
intervalref.current = window.setInterval(set_balance, 1000);
} else {
if (intervalref.current !== null) {
window.clearInterval(intervalref.current);
intervalref.current = null;
}
}
return () => {
if (intervalref.current !== null) {
window.clearInterval(intervalref.current);
}
};
}, [set_balance, wallet]);
Here wallet comes from a 3rd party library and is used to get the users balance.
set_balance
is then not very complex:
const set_balance = useCallback(async () => {
console.log("in increase", balance, check_balance);
if (wallet === null) return;
if (check_balance === false) return;
let current_balance = await get_current_balance(wallet);
if (current_balance !== balance) {
setCheckBalance(false);
}
setBalance(current_balance);
}, [wallet, balance, check_balance]);
The idea then is that some other function within this component is going to do setCheckBalance(true)
, and then the above will run calling get_current_balance() until a change is detected, at which point the function will just start exiting early (but still runs).
Unfortunately this doesn't work. The interval only runs a couple of times and then stops. However, if I remove the dependencies on balance and check_balance, and replace them with global variables rather than state, it works.
Unfortunately that is a very limited use-case solution, as I want other components in other files to be able to setCheckBalance, whereas they can't set exported global variables.
What is the 'react' way of doing this?
In the return function of your useEffect
, you do not set
intervalref.current = null;
So when the cleanup function of your useEffect
is triggered, you stop your interval, but with all the conditions you have, you never start a new one.
Unralated to your problem, but check_balance
would better be a useRef
than a state, so your useCallback
and useEffect
are not triggered again