React useEffect 使用场景示例

React 的 useEffect 是用于处理副作用(如数据获取、订阅、手动 DOM 操作等)的 Hook。以下是几个常见使用场景的示例:


1. 组件挂载时获取数据

jsx 复制代码
import { useEffect, useState } from 'react';

function DataFetcher() {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    // 定义一个异步函数
    const fetchData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        const result = await response.json();
        setData(result);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    // 清理函数(可选,比如取消请求)
    return () => {
      // 可以在这里取消未完成的请求
    };
  }, []); // 空依赖数组:仅在组件挂载时运行一次

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      {data.map(item => <div key={item.id}>{item.name}</div>)}
    </div>
  );
}

2. 依赖项触发副作用

当某个值(如 count)变化时更新文档标题:

jsx 复制代码
function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]); // 依赖项为 count,当 count 变化时触发

  return (
    <button onClick={() => setCount(count + 1)}>
      Increment ({count})
    </button>
  );
}

3. 添加和移除事件监听器

监听窗口大小变化:

jsx 复制代码
function WindowSizeTracker() {
  const [windowSize, setWindowSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  useEffect(() => {
    const handleResize = () => {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    };

    window.addEventListener('resize', handleResize);

    // 清理函数:组件卸载时移除事件监听
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // 空依赖数组:仅在组件挂载和卸载时运行

  return (
    <div>
      Window size: {windowSize.width} x {windowSize.height}
    </div>
  );
}

4. 定时器(setInterval)

每秒更新一次时间:

jsx 复制代码
function Timer() {
  const [time, setTime] = useState(new Date());

  useEffect(() => {
    const timerId = setInterval(() => {
      setTime(new Date());
    }, 1000);

    // 清理函数:组件卸载时清除定时器
    return () => clearInterval(timerId);
  }, []); // 空依赖数组:定时器只初始化一次

  return <div>Current time: {time.toLocaleTimeString()}</div>;
}

5. 依赖项为空 vs 无依赖

  • 空依赖数组 []:仅在组件挂载时运行一次。
  • 无依赖数组:每次组件渲染后都会运行。
  • 特定依赖 [dep1, dep2]:当依赖项变化时运行。

注意事项

  1. 避免无限循环 :如果依赖项是引用类型(如对象或数组),需确保它们的引用稳定(比如使用 useMemo)。

  2. 异步操作 :直接在 useEffect 中使用 async 函数会报错,但可以在内部定义 async 函数并调用:

    jsx 复制代码
    useEffect(() => {
      const fetchData = async () => { /* ... */ };
      fetchData();
    }, []);
  3. 清理副作用:始终为需要清理的操作(如事件监听、定时器)返回清理函数。

通过合理使用 useEffect,可以管理组件的生命周期和副作用逻辑。

相关推荐
程序员与背包客_CoderZ35 分钟前
Node.js异步编程——Callback回调函数实现
前端·javascript·node.js·web
非凡ghost1 小时前
Pale Moon:速度优化的Firefox定制浏览器
前端·firefox
清灵xmf1 小时前
从 Set、Map 到 WeakSet、WeakMap 的进阶之旅
前端·javascript·set·map·weakset·weakmap
11054654012 小时前
11、参数化三维产品设计组件 - /设计与仿真组件/parametric-3d-product-design
前端·3d
爱笑的林羽2 小时前
Mac M系列 安装 jadx-gui
前端·macos
运维@小兵2 小时前
vue使用路由技术实现登录成功后跳转到首页
前端·javascript·vue.js
肠胃炎2 小时前
React构建组件
前端·javascript·react.js
邝邝邝邝丹2 小时前
React学习———React.memo、useMemo和useCallback
javascript·学习·react.js
酷爱码2 小时前
HTML5表格语法格式详解
前端·html·html5
hello_ejb32 小时前
聊聊JetCache的缓存构建
java·前端·缓存