You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

对应到你的代码场景:

  1. 组件首次挂载时,严格模式让组件函数执行两次,所以会打印两次空数组。
  2. 当fetch请求完成并调用setCountries更新状态后,组件重新渲染,严格模式又让这次渲染执行两次,因此会打印两次填充后的数组。
    最终就出现了四次日志输出,和你截图里的情况完全匹配。

处理建议

  • 生产环境下严格模式会自动禁用,不会出现这种重复渲染的情况,无需担心线上表现。
  • 如果只是开发时不想看到重复日志,可以暂时移除根组件外层的<StrictMode>标签,但不推荐这么做——严格模式能帮你提前规避很多隐蔽问题。
  • 更合理的做法是把console.log放到依赖countries的useEffect里,只在状态变化时打印:
useEffect(() => {
  console.log(countries);
}, [countries]);

这样只会在countries状态更新时触发打印,不会因为组件重复渲染产生多余日志。

内容的提问来源于stack exchange,提问作者lechnerio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:54:17