below is code. runonce function does nt work as (it should run only once in 3000ms) but if i does not update state then it works fine.
const HomeScreen = ({ navigation }) => {
const [count, setCount] = useState(1)
function runOnce(func, delay) {
let timer = null;
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
timer = null;
}, delay);
return func(...args);
}
};
}
const handleButtonClick = runOnce(() => {
console.log("This function will run only once in 3000 milliseconds");
//here if i don't update below state then console runs only once in 3000ms
// but if i update state then it runs whenever i click button
setCount(prev => prev + 1)
}, 3000);
return <SafeAreaView style={{ flex: 1 }}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ margin: 10, color: 'red', fontSize: 24 }}>{count}</Text>
<TouchableOpacity style={{ marginTop: 10 }} onPress={() => handleButtonClick()}>
<Text style={{ color: 'blue' }}>Increment Count</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
}
as expected the function inside runonce should run only once in every 3000ms no mattar how many times you click
When updating state, your function reruns and reconstructs your click handler to be a new function on every render, each time with a new timer.
To avoid this, memoize the function using useCallback.
const handleButtonClick = useCallback(() => runOnce(() => {
console.log("This function will run only once in 3000 milliseconds");
//here if i don't update below state then console runs only once in 3000ms
// but if i update state then it runs whenever i click button
setCount(prev => prev + 1)
}, 3000), []);