React中闭包陷阱的几种情况,如何解决?

什么是闭包?

闭包是指在一个函数内部包裹函数,并且内部函数总能访问外部函数的变量。

function f1(){
    var num = 10,
    function f2(){
        alert(num)  // 10
    }
}

特点:1:函数套函数;

           2:内部函数可以直接使用外部函数的局部变量或参数;

           3:变量或参数不会被垃圾回收机制回收 GC

缺点:常驻内存 会增大内存的使用量 使用不当会造成内存泄露。

闭包陷阱以及如何解决

在react中我们使用其提供的Hooks中的useState,useEffect,useCallback 时,可能会造成闭包陷阱,下面我们来看一下出现的情况以及如何解决

useState【异步陷阱】

 const [num, setNum] = useState(0)
  const jia = () => {
    setNum(num + 1)
    console.log(num);
  }
  return (
    <div>
      <h1>{num}</h1>
      <button onClick={() => jia()}>点我+1</button>
    </div>
  )

问题:当我们点击button按钮时,会发现值在持续 +1 ,但是打印的值始终都是上一次点击的值,

因为useState修改值是异步更新,无法获取更新后的值

解决方案:

const [num, setNum] = useState(0)
  const numRef = useRef()
  const jia = () => {
    setNum(num + 1)
    setTimeout(() => {  //模拟异步操作
      console.log(numRef.current.innerText);
    }, 0)
  }
  return (
    <div>
      <h1 ref={numRef}>{num}</h1>
      <button onClick={() => jia()}>点我+1</button>
    </div>
  )

使用useRef来获取元素的值 

useEffect【过期问题】

const [num, setNum] = useState(0)

  useEffect(() => {
    setInterval(() => {
      setNum(num + 1)
    }, 1000)
  }, [])

  return (
    <div>
      <h1>{num}</h1>
    </div>
  )

问题:useEffect是在页面加载时执行,如果第二个参数是一个空数组,则只执行一次,所以我们可以看到页面始终显示的都是1

解决方案:

const [num, setNum] = useState(0)

  useEffect(() => {
    let time = setInterval(() => {
      setNum(num + 1)
      clearInterval(time)
    }, 1000)
  }, [num])

  return (
    <div>
      <h1>{num}</h1>
    </div>
  )

我们可以通过在空数组中传入依赖项,使得useEffect中的逻辑在num每次更改时都会执行,并在每次执行后都清楚掉定时器

useCallback【缓存问题】

useCallback是用来进行优化的函数,他的作用是返回一个记忆化的回调函数,该回调函数仅在其依赖项发生变化时才会更新。这在处理子组件的 props 或者优化事件处理函数等场景中非常有用。

我们在父组件向子组件传递数据,并在父组件修改值,我们会发现,子组件的useCallback中打印的一直都是0

解决方案:我们在useCallback的空数组中,传入我们的依赖项 props.num 这样每次props.num 发生改变就会重新执行代码

以上就是我们在使用React的Hooks中可以会遇到的一些闭包陷阱以及解决方案~

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值