猿问

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

如果我在没有 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>

        )

    }


宝慕林4294392
浏览 114回答 3
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);.....

幕布斯6054654

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

慕码人2483693

Dan Abramov 解释了为什么这不是一个好主意:“这不是惯用的方法。例如,如果您有同一组件的多个实例,它将无法正常工作。它违反了规则——它在渲染过程中产生了副作用(setInterval),页面上说你不应该这样做做 :) 一旦你违反了规则,所有的赌注都取消了”
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答