【问题标题】:Function inside "setInterval" does not recieve updated variables from hooks“setInterval”中的函数不接收来自钩子的更新变量
【发布时间】:2019-12-19 16:05:42
【问题描述】:

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

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

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

//不用钩子就可以了;

【问题讨论】:

标签: reactjs setinterval react-hooks


【解决方案1】:

由于 calculateCircle 实例最初只是从 useEffect 挂钩中引用的,因此它在创建此函数时从闭包中获取 xCircle 和 mouseIn 值,而 setInterval 是在初始调用时。

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

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

【讨论】:

    猜你喜欢
    • 2021-05-24
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 2019-09-23
    • 1970-01-01
    相关资源
    最近更新 更多