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

如何解决React中的'Maximum update depth exceeded'警告

解决React「Maximum update depth exceeded」无限循环警告

问题分析

你提供的FilterSearch组件代码里没有直接调用setState,但出现该警告的核心原因是组件或其父组件存在无限重渲染循环,常见触发场景包括:

  • 父组件传递的produtos、params等props每次渲染生成新引用,导致当前组件被迫重复渲染
  • 组件内部计算的结果(如过滤后的数组)触发父组件状态更新,形成循环
  • 依赖项不稳定,导致相关hooks重复执行

针对性修复方案

1. 缓存过滤结果,稳定引用

当前组件每次渲染都会重新执行过滤逻辑,生成新的数组引用,可能触发不必要的重渲染。用useMemo缓存过滤结果,仅在依赖项变化时重新计算:

import { useMemo } from 'react';

const FilterSearch = ({ produtos, params }) => {
  // 缓存过滤后的数组,仅当依赖项变化时重新计算
  const filter = useMemo(() => {
    let result = produtos;
    if (params.searchType === "CategoriaProduto") {
      result = produtos.filter(item => 
        item.categoria === params.searchContent?.toString()
      );
    } else if (params.searchType === "Componente" && params.searchContent != null) {
      result = produtos.filter(item => 
        item.nome.includes(params.searchContent)
      );
    }
    return result;
  }, [produtos, params.searchType, params.searchContent]); // 仅添加实际用到的字段作为依赖

  // 提取函数到外层,避免每次map创建新函数
  const getLowest = (locaisVendas) => {
    if (locaisVendas.length >= 1) {
      return locaisVendas.reduce((prev, curr) => 
        curr.preco < prev.preco ? curr : prev
      );
    }
    return null;
  };

  return (
    filter.map(componente => {
      const menorPreco = getLowest(componente.locaisVendas);
      return (
        <tr className="mt-2 my-3" key={componente.id}>
          <th className="py-3" >
            <img src="/among_us2.png" className="img-fluid" alt="Imagem responsiva" style={{ width: '100px', height: '100px', }} />
            &emsp;{componente.nome}
          </th>
          <th className="col-md-2">
            <label className="form-check-label fa fa-star text-warning" htmlFor="defaultCheck1"></label>
            <label className="form-check-label fa fa-star text-warning" htmlFor="defaultCheck1"></label>
            <label className="form-check-label fa fa-star text-warning" htmlFor="defaultCheck1"></label>
            <label className="form-check-label fa fa-star text-warning" htmlFor="defaultCheck1"></label>
            <label className="form-check-label fa fa-star text-muted" htmlFor="defaultCheck1"></label>
          </th>
          <th>R$ {menorPreco?.preco}</th>
          <th>{menorPreco?.vendedor}</th>
          <th>
            <Link to={`/Search/Product/${componente.id}`}>
              <button className="btn-details rounded p-2"><i className="fa-sharp fa-solid fa-plus mx-1"></i> Ver mais detalhes</button>
            </Link>
          </th>
        </tr>
      );
    })
  );
};

2. 稳定父组件传递的props

如果produtos或params是父组件传递的:

  • 避免在父组件渲染时创建新的数组/对象,比如不要直接写<FilterSearch params={{ searchType: 'xxx' }} />,而是用useMemo缓存:
    // 父组件中
    const params = useMemo(() => ({
      searchType: 'xxx',
      searchContent: 'yyy'
    }), [相关依赖]); // 仅当依赖变化时更新params
    
    <FilterSearch params={params} produtos={produtos} />
    
  • 如果produtos是父组件的状态,确保它的引用稳定,不要每次渲染重新生成数组。

3. 排查父组件的状态更新逻辑

如果上述修改后问题仍存在,检查父组件是否:

  • 把FilterSearch的输出作为状态更新的依赖,导致每次组件渲染都触发父组件setState
  • 在渲染阶段调用了会触发重渲染的操作(如navigate、setState)

4. 优化内部函数定义

用useCallback缓存getLowest函数,进一步减少不必要的重渲染:

import { useMemo, useCallback } from 'react';

// ...

const getLowest = useCallback((locaisVendas) => {
  if (locaisVendas.length >= 1) {
    return locaisVendas.reduce((prev, curr) => 
      curr.preco < prev.preco ? curr : prev
    );
  }
  return null;
}, []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:07:27