为了账号安全,请及时绑定邮箱和手机立即绑定

如何在没有useEffect的情况下使用setInterval

如何在没有useEffect的情况下使用setInterval

宝慕林4294392 2023-04-27 10:13:09
如果我在没有 useEffect 的情况下使用 setInterval(line 15) 而不是它给出的结果 2^n-1(0,1,3,7,15,31,63...) 而不是 (0,1,2,3,4, ..)。所以我有一些问题1)为什么我在不使用 useEffect 的情况下直接调用 setInterval 时得到那个输出 2)如果我更改 setCount(第 9 行)并且它通过直接使用 setInterval 而不使用 useEffect(就像我所做的那样)给出正确的输出,有什么办法吗3) 如果没有 useEffcet 就不能使用 setInterval 那么为什么不能呢?如果我将 setInterval 放在 useEffect 中并最初渲染一次(第 12、13、14 行)而不是它给出正确的输出......但是当我直接使用 setInterval 时我没有得到正确的输出。什么是差异赌注?在这两种情况下,我都调用了一次 setInterval,但输出是不同的。import React, {useEffect, useState } from 'react'        export default function IncorrectDependency() {        const [count,setCount]=useState(0)        const inc=()=>{        // console.log(count)        setCount(preVal=>preVal+1)    //    setCount(count+1)    }    // useEffect(()=>{    //     setInterval(inc,1000)},[]    // )    setInterval(inc,1000)            return (            <div>                <h1>{count}</h1>                           </div>        )    }
查看完整描述

3 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

当我们设置状态时,功能组件会从上到下重新执行,但是当我们使用 useState、useCallbacks 等时,它们不会重新初始化为变量、函数、

所以在这种情况下,setInterval将重新初始化每个setCount,因为状态发生了变化,

一步步

  • 在第 1 秒会有一个 setInterval,调用 setCount 组件准备好重新渲染

  • 重新渲染时,开始从上到下执行它再次看到的功能组件,setInterval它会触发它,所以现在我们有两个setIntervals

  • 所以它会在每一秒添加多个setIntervals,因为我们没有清除它,所以你应该看到浏览器中打印的数字不会花费一秒钟,但随着时间的推移会不到一秒钟。

您可以在不清除每次重新渲染的先前间隔的情况下获得预期结果,useEffect这是由于setCount

创建一个变量来保存设置的间隔,代码

const interval = null;

//this should be declare out side the component,

//because if we declare it inside the component it will redeclare,

//and the reference to the previous setInterval will be lost in that case no-way to clear the setInterval.

export default function IncorrectDependency() {

    ....

    if (interval) {

        clearInterval(interval);

    }


    interval = setInterval(inc, 1000);

    ....

 }

或者 React 有一个钩子,它可以保存相同的变量而无需在每个渲染上重新初始化,


const intvl = useRef(null);

....


if (intvl?.current) {

    clearInterval(intvl.current);

}


intvl.current = setInterval(inc, 1000);

.....


查看完整回答
反对 回复 2023-04-27
?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

当您直接使用 setInterval 时发生了什么,因为这是一个函数,它将在状态更改时被调用,因此将再次触发 setInterval 等等,这实际上会给您不正确的结果,因此您不应该在没有使用效果的情况下使用 setInterval,也在卸载时你应该清除间隔



查看完整回答
反对 回复 2023-04-27
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

Dan Abramov 解释了为什么这不是一个好主意:

“这不是惯用的方法。例如,如果您有同一组件的多个实例,它将无法正常工作。它违反了规则——它在渲染过程中产生了副作用(setInterval),页面上说你不应该这样做做 :) 一旦你违反了规则,所有的赌注都取消了”

查看完整回答
反对 回复 2023-04-27
  • 3 回答
  • 0 关注
  • 113 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信