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

解决React中useEffect调用setState引发的无限渲染问题

解决React组件无限重渲染(Maximum update depth exceeded)问题

问题背景

组件运行时出现以下警告:

Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.

问题出在这段useEffect代码:

useEffect(() => {
  if (data?.meta) {
    setPagination({
      showPrev: data.meta.has_previous_page,
      showNext: data.meta.has_next_page
    });
  }
}, [data?.meta]);

问题原因

每次API请求返回的data.meta都是新的对象引用(即使里面的has_previous_page和has_next_page值没有变化),导致useEffect的依赖data?.meta被判定为“变化”,进而触发setPagination更新状态。状态更新会引发组件重渲染,重渲染后data.meta又变成新引用,再次触发useEffect,形成无限循环。

解决方案

方案1:依赖具体属性而非整个对象

直接监听data.meta里的具体布尔值,只有当这些值真正变化时才执行更新:

useEffect(() => {
  if (data?.meta) {
    setPagination({
      showPrev: data.meta.has_previous_page,
      showNext: data.meta.has_next_page
    });
  }
}, [data?.meta.has_previous_page, data?.meta.has_next_page]);

优点:简单直接,避免对象引用变化导致的无效触发,推荐使用。

方案2:手动浅比较+useRef跟踪旧值

用useRef存储上一次的meta状态,在useEffect里做浅比较,只有属性值变化时才更新:

import { useRef } from 'react';

// ...

const prevMetaRef = useRef<typeof data.meta>();

useEffect(() => {
  if (data?.meta) {
    const currentMeta = data.meta;
    // 对比关键属性是否变化
    const hasUpdated = 
      prevMetaRef.current?.has_previous_page !== currentMeta.has_previous_page ||
      prevMetaRef.current?.has_next_page !== currentMeta.has_next_page;

    if (hasUpdated) {
      setPagination({
        showPrev: currentMeta.has_previous_page,
        showNext: currentMeta.has_next_page
      });
      prevMetaRef.current = currentMeta;
    }
  }
}, [data?.meta]);

优点:适合需要依赖整个对象但要避免无效更新的场景,灵活性高。

方案3:直接派生计算,无需单独状态

由于pagination完全由data.meta派生而来,不需要用useState维护,直接在渲染时计算即可:

// 移除原有的const [pagination, setPagination] = useState<PaginatorProps>();

// 在需要使用pagination的地方直接计算
const pagination = data?.meta ? {
  showPrev: data.meta.has_previous_page,
  showNext: data.meta.has_next_page
} : undefined;

优点:最简洁,减少状态管理成本,从根源避免循环问题,优先考虑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:41:30