React 纠错:忘记添加依赖到 useEffect —— 从“死循环”到“过期闭包”一次排雷

当你在控制台看到:

React Hook useEffect has a missing dependency: 'xxx'

React 在提醒你:
「effect 里用到了 xxx,但依赖数组没写它」
这会导致 2 种后果:

  1. 过期闭包:拿到旧值;
  2. 死循环:依赖变化但 effect 不重新执行。

本文用「原理 → 场景 → 修复」三步法,3 分钟解决所有漏依赖问题。


一、为什么漏依赖会翻车?

React 依赖数组 = effect 的“触发器”

  • 写了 → 变化时重新执行;
  • 没写 → 永远拿到第一次的闭包值。

二、4 个高频翻车现场 & 修复

1️⃣ 过期闭包:永远拿不到最新值

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      console.log(count); // ❌ 永远打印 0
    }, 1000);
  }, []); // 漏写 count
}

修复:补全依赖

useEffect(() => {
  const id = setInterval(() => console.log(count), 1000);
  return () => clearInterval(id);
}, [count]); // ✅

2️⃣ 死循环:依赖变化但 effect 不执行

function Search({ keyword }) {
  const [results, setResults] = useState([]);

  useEffect(() => {
    fetchResults(keyword).then(setResults); // ❌ keyword 变化但 effect 不重新执行
  }, []); // 漏写 keyword
}

修复:补全依赖

useEffect(() => {
  fetchResults(keyword).then(setResults);
}, [keyword]); // ✅

3️⃣ 函数依赖被忽视

function Parent() {
  const handleClick = () => console.log('click');

  useEffect(() => {
    window.addEventListener('click', handleClick); // ❌ handleClick 变化但 effect 不重新绑定
  }, []); // 漏写 handleClick
}

修复:用 useCallback 稳定依赖

const handleClick = useCallback(() => console.log('click'), []);
useEffect(() => {
  window.addEventListener('click', handleClick);
  return () => window.removeEventListener('click', handleClick);
}, [handleClick]); // ✅

4️⃣ 对象/数组每次新引用

const config = { threshold: 0.5 };
useEffect(() => {
  observer = new IntersectionObserver(callback, config);
}, [config]); // ❌ config 每次都是新对象 → 死循环

修复:只传必要值

const threshold = 0.5;
useEffect(() => {
  observer = new IntersectionObserver(callback, { threshold });
}, [threshold]); // ✅

三、ESLint 自动补全(推荐)

安装插件:

npm i -D eslint-plugin-react-hooks

配置:

{
  "extends": ["react-app"],
  "rules": {
    "react-hooks/exhaustive-deps": "warn"
  }
}

VS Code 保存时自动修复:

"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
}

四、一句话总结

「依赖数组 = 副作用的 blood 型」
谁被用,谁就要写进去;
让 ESLint 帮你补全,永不过期、永不循环。


最后问候亲爱的朋友们,并邀请你们阅读我的全新著作

📚 《 React开发实践:掌握Redux与Hooks应用 》

在这里插入图片描述

更多推荐