reactjs - "setInterval"内的函数未从钩子(Hook)接收更新的变量

标签 reactjs setinterval react-hooks

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

我将组件更改为基于类的组件(没有钩子(Hook)),现在一切正常。 但我想知道使用钩子(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);
    }
}, []);

//没有钩子(Hook)也能工作;

最佳答案

由于calculateCircle实例最初仅在useEffect钩子(Hook)内引用,因此它在创建该函数时从闭包中获取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]);

关于reactjs - "setInterval"内的函数未从钩子(Hook)接收更新的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57471987/

相关文章:

javascript - AngularJS 通知模型更改的 View

javascript - ExpressJS : How to know when a request has finished?

reactjs - 为什么 useEffect 不会在每次渲染时触发?

reactjs - React函数式组件执行多次,useSelector()在每次函数式组件执行时执行多次

javascript - 时刻验证仅适用于 React Native 中的某些设备

javascript - 从 CSS 模块中访问全局类

javascript - 如何延迟传递 props 直到 setState() 完成?

javascript - 延迟关闭窗口javascript

javascript - 将 leaflet-control-geocoder 与 react-leaflet 一起使用

javascript - 如何解析url查询字符串中的完整链接?