简体   繁体   English

当我更新此函数内的状态时,油门函数不起作用

[英]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. runonce函数不能正常工作(它应该只在 3000 毫秒内运行一次)但是如果我不更新状态那么它工作正常。

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正如预期的那样,runonce 中的函数应该每 3000 毫秒只运行一次,不管你点击多少次

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.为避免这种情况,请使用 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.但是 Javascript 已经借助这两个函数帮助我们做到这一点。

setInterval() - To run a function with a given interval in ms. setInterval() - 以毫秒为单位以给定的时间间隔运行函数。 ( https://www.w3schools.com/jsref/met_win_setinterval.asp ) ( https://www.w3schools.com/jsref/met_win_setinterval.asp )

setTimeout() - To run a function after a certain time delay in ms. setTimeout() - 在以毫秒为单位的特定时间延迟后运行函数。 ( https://www.w3schools.com/jsref/met_win_settimeout.asp ) ( https://www.w3schools.com/jsref/met_win_settimeout.asp )

I hope this helps you to reduce the redundant code you have.我希望这可以帮助您减少您拥有的冗余代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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