useEffect 为什么在每次渲染后都执行?

Top丶佳妮 阅读 23

我在组件里用 useEffect 做数据请求,但发现每次 state 更新它都会重新跑一遍,明明只希望在组件挂载时调一次。我试过不加依赖数组,也试过加空数组,但行为还是不对,是不是哪里理解错了?

比如下面这段代码,点击按钮更新 count 后,useEffect 里的 log 又打印了:

useEffect(() => {
  console.log('fetching data...');
  // 模拟请求
}, []); // 这里用了空依赖数组啊

const [count, setCount] = useState(0);
我来解答 赞 2 收藏
二维码
手机扫码查看
2 条解答
怡彤
怡彤 Lv1
你这段代码看起来没问题,理论上加空数组应该只在组件挂载时执行一次。但是你遇到的问题可能是因为其他原因导致的。先检查一下你的依赖数组是不是真的没变。另外,确保你的 useEffect 里面没有其他的逻辑错误。你可以试试下面这个简化版的代码,复制过去试试:

pre class="pure-highlightjs line-numbers">import React, { useEffect, useState } from 'react';

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

useEffect(() => {
console.log('fetching data...');
// 模拟请求
}, []); // 注意这里空数组

return (

Count: {count}




);
}

export default MyComponent;


如果这个还是一样有问题,可能是其他地方影响了。再仔细检查一下整个组件的代码吧。
点赞
2026-03-22 08:09
ლ子硕
ლ子硕 Lv1
你的代码其实没问题,空数组确实应该只执行一次。

你说的情况可能是这两个原因之一:

第一,React 18 严格模式在开发环境下会故意挂载-卸载-再挂载一次,用来检测副作用是否正确清理。如果你用了空依赖数组的 effect,你会看到两次 "fetching data...",这是开发模式的特性,生产环境不会这样。

第二,也是更可能的情况——你可能有两个 useEffect,其中一个有依赖 count,或者组件本身被重新挂载了。

你可以这样验证一下:

useEffect(() => {
console.log('组件挂载了');
return () => {
console.log('组件卸载了');
};
}, []);

useEffect(() => {
console.log('count 变化了:', count);
}, [count]);


这样分开写,你就能看清楚是哪个 effect 在执行。

如果你是想在组件挂载时请求数据,然后用空数组就可以了,別担心。开发环境看到两次 log 的话,加上这个就能解决:

// 如果你的 effect 没有清理逻辑,在严格模式下会被执行两次
// 加个简单的 flag 就能避免开发环境的重复请求
useEffect(() => {
let mounted = true;
fetch('/api/data').then(() => {
if (mounted) {
// setState...
}
});
return () => {
mounted = false;
};
}, []);


如果还不是这个问题,把完整的组件代码贴出来,我帮你看看。
点赞
2026-03-18 08:33