React hook的那些坑 理解closure闭包

本文探讨了React Hook中闭包导致的问题,特别是在useEffect中的内存持久化和useRef的不变量存储。通过实例分析和解决策略,帮助理解并避免闭包引发的副作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近开始学习React,跟着Nolan老师开发Jira,有很多干货,这里分享React hook的一个易错点,也就是React Hook中由于closure闭包中会带来的问题以及解决方法


一、Closure的代码段分析

const testClosure = () => {
  let num = 0;
  const effect = () => {
    num += 1;
    const message = `num value in message:${num}`;
    return function unmount() {
      console.log(message);
    };
  };
  return effect;
};

const add = testClosure();
const unmount = add();
add();
add();
add();
unmount(); // 在这里会打印什么呢?

我们一行一行分析

第一行, 执行testClosure,返回引用了message的unmount函数

const add = testClosure();

第二行,返回的是运行effect()的返回值,也是一个函数,unmount(),此时num为1,赋值给unmount

 num += 1;
 const message = `num value in message:${num}`;
 return function unmount() {
   console.log(message);
 };

第三行,add()就是执行unmount(),返回函数unmount(),此时num为2,并没有赋值给其他变量

return function unmount() {
   console.log(message);
 };

第四行,add()就是执行unmount(),返回函数unmount(),此时num为3,并没有赋值给其他变量

return function unmount() {
   console.log(message);
 };

第五行,add()就是执行unmount(),返回函数unmount(),此时num为4,并没有赋值给其他变量

return function unmount() {
   console.log(message);
 };

第六行,运行unmount,也就是运行第二行的返回函数,num为1,所以打印num value in message:1


二、Rect hook中的closure

2.1 useEffect中的闭包

对于useEffect来说,它会与函数组件形成闭包,也就是useEffect中num的值是Test中num开始的值,为0

export const Test = () => {
  const [num, setNum] = useState(0);
  const add = () => setNum(num + 1);
  
  useEffect(() => {
    return () => {
      console.log("卸载值:", num);
    };
  }, []);
  
  return (
    <div>
      <button onClick={add}>add</button>
      <p>number: {num}</p>
    </div>
  );
};

那么解决方法就是在useEffect最后的[]中加上num,告诉React每当num改变的时候都需要重新执行一遍

2.2 useRef

那么既然组件中变量是可变的,那么有没有方法保存一个不变的量呢,这就需要用到useRef

useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.


总结

如果在useEffect遇到闭包问题的话,一定要检查依赖是否正确

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值