'React native infinite useEffect re-render
There's a part of chess clocks. I have a problem with endless re-renders. Idea of this part of app is pushing a one player's button leads to go opponent's time.
const App = () => {
//initialize white
const [whiteTime, setWhiteTime] = useState(10*60);
const [isWhiteMove, setIsWhiteMove] = useState(false);
useEffect(()=>{//make a whiteTime go countown and stop a blackTime
if (isWhiteMove) {
setIsBlackMove(false); //both isWhiteMove and isBlackMove can't be true at the same time
var ID_whiteTimer = setInterval(()=>{
while (prevWhiteTime>0) setWhiteTime(prevWhiteTime => prevWhiteTime-1)}, 1000);} //do countdown every sec
// stopping a whiteTime if isWhiteMove=false
return () => {clearInterval(ID_whiteTimer)};
}, [isWhiteMove]); //do not rerender if thoose aren't changes
//initialize black
const [blackTime, setBlackTime] = useState(10*60);
const [isBlackMove, setIsBlackMove] = useState(false);
useEffect(()=>{//make a blackTime go countown and stop a whiteTime
if (isBlackMove) {
setIsWhiteMove(false); //both isWhiteMove and isBlackMove can't be true at the same time
var ID_blackTimer = setInterval(()=>{
while(prevBlackTime>0) setBlackTime(prevBlackTime => prevBlackTime-1)}, 1000);} //do countown black every sec
// stopping a blackTime if isBlackMove=false
return ()=> {clearInterval(ID_blackTimer)};
}, [isBlackMove]);//do not rerender if thoose aren't changed
return(
<View style={styles.mainCoitainer} >
<StatusBar hidden={true}/>
{/* BLACK BUTTON */}
<TouchableOpacity onPress={setIsWhiteMove(true)} style={styles.opponentButton}>
<View>
<Text>BLACK</Text>
<Text style={styles.timerText}>
{Math.floor((blackTime/(60*60))%24)}:
{Math.floor((blackTime/60)%60)}:
{Math.floor(((blackTime)%60))}
</Text>
</View>
</TouchableOpacity>
{buttonBar()}
{/* WHITE BUTTON */}
<TouchableOpacity onPress={setIsBlackMove(true)} style={styles.playerButton}>
<View>
<Text>WHITE</Text>
<Text style={styles.timerText}>
{Math.floor((whiteTime/(60*60))%24)}:
{Math.floor((whiteTime/60)%60)}:
{Math.floor(whiteTime%60)}
</Text>
</View>
</TouchableOpacity>
</View>
);
}
I use useEffect for handling changes of isWhiteMove and isBlackMove. So, probably problem is somewhere here. So, the algorithm of useEffect handling should be next. For example, black button is pressed. OnPress changes an isWhiteMove state. Changing of isWhiteMove trigger an useEffect, which make blackTime off and start whiteTime countdown. When isWhiteMove going to false, it cleans the timer and do nothing. It's how it's supposed to be. I absolutely have no idea what's going wrong.
I've found some similar questions in stackoverflow, but no one of them helped me.
UPD: as the one of probably reasons, changed a "while" to "if", but it still the same
Solution 1:[1]
your problem is while and the timer. the timer is changing its value many times in one second (that's how timers work in electronics), which causes the useffect to rerender when isBlackMove has changed.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mehdi Khalfallah |
