“setInterval"内的函数不从钩子接收更新的变量 [英] Function inside "setInterval" does not recieve updated variables from hooks

查看:47
本文介绍了“setInterval"内的函数不从钩子接收更新的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 useEffect-hook 中,我设置了运行函数calculateCircle"的间隔.在那里我做了一些逻辑,包括设置状态(使用 useState-Hook).来自钩子的变量被更新,我渲染并在页面上看到它们,但这个函数不断地合并旧值.

In useEffect-hook I set interval, which is running function "calculateCircle". There I do some logic, including setting state(with useState-Hook). Variables from hooks are updated, I render and see them on page, but this function keeps consolloging old values.

我将我的组件更改为基于类的组件(没有钩子),现在一切正常.但我想知道使用钩子的问题是什么.

I changed my component to the class-based component (without hooks) and everything is working now. But I wonder which is the problem using hooks.

const Features = () => {
 const block1 = React.createRef();
 const shadowText = React.createRef();

 const [ mouseIn, setMouseIn ] = useState(false);
 const [ xCircle, setXCircle] = useState(-50);

 const calculateCircle = () => {
    console.log('mouseIn :', mouseIn); //never changes, but in page - yes

    if (!mouseIn) {  //never skips this loop
        console.log('begin', xCircle);//always the same            
        let r = 50;
        let yCircle = Math.sqrt(r*r - xCircle*xCircle);
        if (shadowText.current) draw(xCircle, yCircle);
        setXCircle(prev => {
            console.log('xCircle:', prev);
            return prev > 50 ? -50 : prev + 1
        });            
        console.log('end', xCircle, yCircle);
    }            
} //on page I see that xCircle changes correctly

useEffect(() => {
    const cycle = setInterval(() => calculateCircle(), 1000);
    return () => {
        clearInterval(cycle);
    }
}, []);

//没有钩子就可以工作;

//without hooks it works;

推荐答案

由于 calculateCircle 实例最初仅从 useEffect 钩子内部引用,因此它从创建此函数时的闭包中获取 xCircle 和 mouseIn 值,用于setInterval 处于初始调用状态.

Since calculateCircle instance is only refererrenced initially from within the useEffect hook, it takes the xCircle and mouseIn value from the closure at the time this function was created which for the setInterval is on initial call.

您需要将第二个参数传递给 useEffect 以便在 xCircle 或 mouseIn 更改时再次创建此方法

You need to pass the second argument to useEffect so that this method is created again on xCircle or mouseIn changes

const Features = () => {
 const block1 = React.createRef();
 const shadowText = React.createRef();

 const [ mouseIn, setMouseIn ] = useState(false);
 const [ xCircle, setXCircle] = useState(-50);

 const calculateCircle = () => {
    console.log('mouseIn :', mouseIn); //never changes, but in page - yes

    if (!mouseIn) {  //never skips this loop
        console.log('begin', xCircle);//always the same            
        let r = 50;
        let yCircle = Math.sqrt(r*r - xCircle*xCircle);
        if (shadowText.current) draw(xCircle, yCircle);
        setXCircle(prev => {
            console.log('xCircle:', prev);
            return prev > 50 ? -50 : prev + 1
        });            
        console.log('end', xCircle, yCircle);
    }            
} //on page I see that xCircle changes correctly

useEffect(() => {
    const cycle = setInterval(() => calculateCircle(), 1000);
    return () => {
        clearInterval(cycle);
    }
}, [mouseIn, xCircle]);

这篇关于“setInterval"内的函数不从钩子接收更新的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆