简体   繁体   中英

throttle function does not work when i update state inside this function

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), []);

I can see that you have created your own function for doing an interval breakout or delay to run a function. But Javascript already helps us to do this with the help of these two functions.

setInterval() - To run a function with a given interval in ms. ( https://www.w3schools.com/jsref/met_win_setinterval.asp )

setTimeout() - To run a function after a certain time delay in ms. ( https://www.w3schools.com/jsref/met_win_settimeout.asp )

I hope this helps you to reduce the redundant code you have.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM