首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >react hooks useEffect 用法

react hooks useEffect 用法

原创
作者头像
小焱
发布2025-08-14 19:17:26
发布2025-08-14 19:17:26
16000
代码可运行
举报
文章被收录于专栏:前端开发前端开发
运行总次数:0
代码可运行

useEffect 是 React Hooks 中用于处理副作用的核心钩子,可模拟类组件中的生命周期方法,如 componentDidMountcomponentDidUpdatecomponentWillUnmount。以下是其详细用法:

基本语法

代码语言:javascript
代码运行次数:0
运行
复制
useEffect(() => {
  // 副作用逻辑(如数据请求、事件监听、DOM操作等)
  
  return () => {
    // 清理函数(可选):组件卸载或依赖变化前执行
  };
}, [dependencies]); // 依赖数组(可选)

核心用法

1. 模拟 componentDidMount(只执行一次)

空依赖数组 [] 表示副作用仅在组件挂载后执行一次。

代码语言:javascript
代码运行次数:0
运行
复制
useEffect(() => {
  console.log('组件挂载完成');
  // 示例:初始化数据请求
  fetchData();
}, []); // 空依赖 → 只执行一次
2. 模拟 componentDidUpdate(依赖变化时执行)

依赖数组中指定变量,当这些变量变化时,副作用会重新执行。

代码语言:javascript
代码运行次数:0
运行
复制
const [count, setCount] = useState(0);

// 当 count 变化时执行
useEffect(() => {
  console.log(`count 变为: ${count}`);
  // 示例:根据 count 发送请求
  fetch(`/api/data?count=${count}`);
}, [count]); // 依赖 count → count 变化时执行
3. 模拟 componentWillUnmount(清理副作用)

返回的清理函数会在组件卸载或依赖变化前执行,用于清除定时器、事件监听等。

代码语言:javascript
代码运行次数:0
运行
复制
useEffect(() => {
  // 示例:添加事件监听
  const handleResize = () => console.log('窗口大小变化');
  window.addEventListener('resize', handleResize);

  // 清理函数:移除事件监听
  return () => {
    window.removeEventListener('resize', handleResize);
  };
}, []); // 空依赖 → 组件卸载时执行清理
4. 无依赖数组(每次渲染后执行)

不指定依赖数组时,副作用会在每次组件渲染后执行(包括初始挂载和所有更新)。

代码语言:javascript
代码运行次数:0
运行
复制
useEffect(() => {
  console.log('组件渲染完成(每次更新都会执行)');
}); // 无依赖 → 每次渲染后执行

常见场景示例

示例 1:定时器管理
代码语言:javascript
代码运行次数:0
运行
复制
const [time, setTime] = useState(0);

useEffect(() => {
  // 启动定时器
  const timer = setInterval(() => {
    setTime(prev => prev + 1);
  }, 1000);

  // 清理定时器
  return () => clearInterval(timer);
}, []); // 空依赖 → 只启动一次定时器
示例 2:数据请求与加载状态
代码语言:javascript
代码运行次数:0
运行
复制
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [id, setId] = useState(1);

useEffect(() => {
  // 重置加载状态
  setLoading(true);
  
  // 请求数据
  const fetchData = async () => {
    try {
      const res = await fetch(`/api/item/${id}`);
      const result = await res.json();
      setData(result);
    } catch (err) {
      console.error('请求失败:', err);
    } finally {
      setLoading(false);
    }
  };

  fetchData();

  // 清理函数:若 id 变化,取消当前请求(需配合 AbortController)
  const controller = new AbortController();
  return () => controller.abort();
}, [id]); // 依赖 id → id 变化时重新请求

注意事项

  1. 依赖数组必须完整undefined副作用中使用的所有状态/变量都必须加入依赖数组,否则可能导致使用旧值。
代码语言:javascript
代码运行次数:0
运行
复制
   // 错误示例:依赖了 count 却未加入依赖数组
   useEffect(() => {
     console.log(count); // 可能输出旧值
   }, []); // 遗漏了 count 依赖
  1. 清理函数的执行时机undefined清理函数会在下次副作用执行前组件卸载时触发,确保资源正确释放。
  2. 避免无限循环undefined若副作用中修改了依赖数组中的变量,需确保逻辑不会导致无限更新:
代码语言:javascript
代码运行次数:0
运行
复制
   const [count, setCount] = useState(0);

   // 危险:修改了依赖变量 count,会导致无限循环
   useEffect(() => {
     setCount(prev => prev + 1);
   }, [count]);
  1. 异步操作处理undefineduseEffect 的回调函数不能直接是异步函数,但可以在内部定义并调用异步函数(如示例 2)。

总结

useEffect 通过依赖数组控制副作用的执行时机,核心原则是:

  • 空依赖 [] → 只执行一次(挂载时)
  • 有依赖 [a, b] → 初始挂载 + ab 变化时执行
  • 无依赖 → 每次渲染后执行
  • 返回的清理函数用于释放资源

合理使用 useEffect 可以清晰地管理组件的副作用逻辑,避免类组件中生命周期方法的冗余。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本语法
  • 核心用法
    • 1. 模拟 componentDidMount(只执行一次)
    • 2. 模拟 componentDidUpdate(依赖变化时执行)
    • 3. 模拟 componentWillUnmount(清理副作用)
    • 4. 无依赖数组(每次渲染后执行)
  • 常见场景示例
    • 示例 1:定时器管理
    • 示例 2:数据请求与加载状态
  • 注意事项
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档