React中useEffect触发多次且console.log频繁输出的原因排查
React组件多次渲染导致console.log触发过多的原因分析
我正在尝试使用React从本地json-server获取数据并展示为列表。按照我的理解,这个场景下useEffect应该触发两次console.log:一次返回空的countries数组,一次返回填充后的数组。但实际控制台中该日志触发次数过多,想知道原因。
React代码:
import React, { useEffect, useState } from 'react' export default function CountryList() { const [countries, setCountries] = useState([]) useEffect(() => { fetch('http://localhost:3001/countries') .then(res => res.json()) .then(data => setCountries(data)) }, []) console.log(countries) return ( <div> <h2>CountryList</h2> <ul> {countries.map(country => ( <li key={country.name}>{country.name}</li> ))} </ul> </div> ) }
控制台实际输出如下:

json-server中的国家列表数据:
{ "countries": [ { "name": "Austria", "code": "AT", "language": "german", "cities": { "Vienna": { "population": "8.3 million", "latitude": "48.208174", "longitude": "16.373819" }, "Graz": { "population": "1.5 million", "latitude": "47.070713", "longitude": "15.439186" } }, "currency": { "code": "EUR", "name": "Euro", "symbol": "€" } }, { "name": "Greece", "code": "GR", "language": "greek", "cities": { "Athens": { "population": "2.7 million", "latitude": "37.983810", "longitude": "23.727539" }, "Thessaloniki": { "population": "1.5 million", "latitude": "40.633125", "longitude": "22.944406" }, "Patras": { "population": "1.5 million", "latitude": "38.244818", "longitude": "21.738050" } }, "currency": { "code": "EUR", "name": "Euro", "symbol": "€" } } ] }
原因分析
你看到多次日志输出,核心原因是React 18开发环境下的严格模式(Strict Mode)。
在React 18的开发模式中,严格模式会刻意重复执行组件函数、useState初始化、useEffect回调等逻辑,目的是提前帮你发现非纯函数、重复副作用这类潜在bug。
对应到你的代码场景:
- 组件首次挂载时,严格模式让组件函数执行两次,所以会打印两次空数组。
- 当
fetch请求完成并调用setCountries更新状态后,组件重新渲染,严格模式又让这次渲染执行两次,因此会打印两次填充后的数组。
最终就出现了四次日志输出,和你截图里的情况完全匹配。
处理建议
- 生产环境下严格模式会自动禁用,不会出现这种重复渲染的情况,无需担心线上表现。
- 如果只是开发时不想看到重复日志,可以暂时移除根组件外层的
<StrictMode>标签,但不推荐这么做——严格模式能帮你提前规避很多隐蔽问题。 - 更合理的做法是把
console.log放到依赖countries的useEffect里,只在状态变化时打印:
useEffect(() => { console.log(countries); }, [countries]);
这样只会在countries状态更新时触发打印,不会因为组件重复渲染产生多余日志。
内容的提问来源于stack exchange,提问作者lechnerio
相关产品推荐
相关产品推荐

