【React】useEffect依赖项总结速记+常用情景代码

首先简单回顾一下官方文档对useEffect的定义:

useEffect 是一个 React Hook,作用是连接外部系统(显示在页面上但不受react控制的系统)

useEffect(setup, dependencies?)

setup 用来连接外部系统的代码,返回一个清理函数(cleanup),用来与该外部系统断开连接

模版:

useEffect(() => {
  // 副作用逻辑(组件挂载或依赖项变化时执行)
  return () => {
    // 清理逻辑(组件卸载或依赖项变化前执行)
  };
}, [dependencies]);

空依赖数组 []

挂载/卸载时执行,即Effect 仅在组件首次渲染后执行一次

场景

  1. 定时器(面试热点)
useEffect(() => {
    const id = window.setInterval(() => {
      setCount(prev => prev + 1);
    }, 2000);
    // 清除定时器,避免组件卸载后计时仍进行
    return () => clearInterval(id);
  }, []); // 空依赖数组:只启动一次间隔逻辑
  1. 初始化api请求
useEffect(() => {
    // 组件挂载时调用 API 获取用户信息
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(setUser)
      .catch(console.error);
    // 无需 cleanup,因为只是一次请求
  }, []); // 空依赖数组:只在首次渲染后运行一次
  1. 添加全局浏览器事件监听(如窗口大小
useEffect(() => {
    const handleResize = () => {
      setSize({ w: window.innerWidth, h: window.innerHeight });
    };
    window.addEventListener('resize', handleResize);
    // cleanup:组件卸载时移除 listener
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // 确保 listener 只设置一次

还有如访问一次性dom元素、websocket订阅

含依赖项的数组 [dep1, dep2] - 条件执行

Effect 在依赖项发生变化时执行,清理函数在依赖项变化导致effect重新执行运行

场景

  1. 表单验证
useEffect(() => {
    const valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    setIsValid(valid);
  }, [email]); // 只在email变化时执行验证,依赖输入值
  1. 订阅更新
function MessageSubscriber({ channelId }) {
  useEffect(() => {
    // 1. 设置订阅:订阅指定频道的消息
    const subscription = subscribe(channelId, msg => {
      console.log("receive:", msg);
    });
    // 2. Cleanup:当组件卸载或 channelId 变化时取消订阅
    return () => {
      subscription.unsubscribe();
    };
  }, [channelId]);// channelId 改变时重建订阅,依赖外部id
}
  1. 数据过滤、排序
// 从后端拉取 items(只需一次)
  useEffect(() => {
    fetch('/api/items').then(res => res.json()).then(setItems);
  }, []);
  // 仅当 filter 或 items 改变时才应用过滤逻辑
  useEffect(() => {
    setFiltered(items.filter(item => item.type === filter));
  }, [filter, items]);

无依赖数组undefined

每次渲染后都执行

useEffect(() => {
  // 每次渲染后都执行(包括首次)
  console.log('每次渲染都执行');

  return () => {
    // 清理函数在每次 effect 重新执行前运行
    console.log('清理前一次 effect');
  };
}); // 无第二个参数

场景

极少使用。最常用的场景:跟踪 DOM 元素尺寸或滚动位置等副作用依赖 UI 的变化

function DebugLogger({ value }) {
  useEffect(() => {
    console.log('组件渲染完成,当前 value:', value);

    return () => {
      console.log('即将重新渲染(或卸载),清理前一次 effect');
    };
  }); // 没有依赖数组:每次渲染都执行

  return <div>{value}</div>;
}

性能开销大,不要滥用

总结

依赖数组执行时机清理函数触发时机
undefined每次渲染后每次重新执行 effect 前
[]仅首次渲染后组件卸载时
[dep1, dep2]依赖项变化时依赖变化导致重新执行 effect 前

参考

  1. https://www.ruanyifeng.com/blog/2020/09/react-hooks-useeffect-tutorial.html
  2. https://zh-hans.react.dev/reference/react/useEffect
  3. https://juejin.cn/post/7034107004918431774
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值