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

如何避免在useEffect中调用修改状态的函数时出现无限循环

React useEffect无限循环问题修复方案

问题根因

  • 组件顶层定义的func没有做引用缓存,每次组件渲染都会生成新的函数实例,而useEffect依赖了func,实例变化就会触发useEffect执行
  • useEffect同时依赖了状态arr,但func内部调用setArr修改arr的值,arr更新后又会触发useEffect重新执行,形成死循环

修复方案

1. 移除无效依赖

不需要把当前arr作为参数传入func,也不要把arr加入useEffect依赖项。如果需要基于旧arr计算新值,使用setArr的函数式更新语法即可,该语法可以直接拿到上一次的arr状态,不需要额外声明依赖。

2. 缓存函数引用

用useCallback包裹func,保证只有指定依赖变化时才更新func的引用,避免无意义的useEffect触发。

修复后示例代码

import { useCallback, useEffect, useState } from 'react'

// 组件内部逻辑
const [arr, setArr] = useState<any[]>([])

// 用useCallback缓存func,仅内部依赖变化时才更新引用
const func = useCallback((val: any) => {
  // 你的原有业务逻辑
  setArr(prevArr => {
    // 基于旧arr和val计算新数组,替换成你的实际逻辑
    const newArr = [...prevArr, ...val]
    return newArr
  })
}, []) // 此处仅添加func内部用到的外部变量作为依赖

useEffect(() => {
  val?.length > 0 && func(val)
}, [val, func])

最简优化方案

如果func仅在当前useEffect中调用,可以直接把逻辑写到useEffect内部,省去函数缓存的步骤:

useEffect(() => {
  if (!val?.length) return
  // 直接写原有func的业务逻辑
  setArr(prevArr => {
    // 计算新数组逻辑
    return newArr
  })
}, [val]) // 仅保留val作为依赖,完全避免循环

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:36:04