Effect 根据它的 dependencies 重新运行,而数组弄错是 #1 React bug 的根源。
为什么这很重要
Effect 会闭包捕获创建它的 render 中的值。如果你忽略某个 dependency,它就会继续使用旧值:
jsx
useEffect(() => {
const id = setInterval(() => {
console.(count);
}, );
(id);
}, []);
修复方式:要么把 count 加到 deps 中,要么使用不需要它的 functional updater(setCount(c => c + 1))。
对象/数组/函数在每次 render 时都被重新创建,所以它们每次都是"新的",effect 永远无法稳定:
const options = { id }; // ❌ new object every render
useEffect(() => { load(options); }, [options]); // runs every render
修复方式:依赖于原始值([id]),或者用 useMemo/useCallback 进行 memoization。
useEffect(() => {
const ctrl = new AbortController();
fetch(url, { signal: ctrl.signal }).then(setData);
return () => ctrl.abort(); // cancels the old request when `url` changes
}, [url]);
没有 cleanup,较早的慢请求可能在较新请求之后才resolve,从而覆盖新数据(竞态条件),订阅/定时器会堆积。ESLint 规则 react-hooks/exhaustive-deps 可以捕获大多数缺少 dependency 的情况。