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

React编辑表单触发Maximum Update Depth Exceeded警告问题

报错根因
  • 组件顶层的sessionStorage清理逻辑、表单初始数据读取逻辑没有包裹在只执行一次的useEffect里,每次组件重渲染都会重复执行这部分逻辑,触发子组件JobForm重渲染
  • 子组件JobForm每次数据变更都会调用父组件传入的getNewData方法修改newData状态,状态更新又会触发父组件重渲染,直接形成「状态更新→父组件重渲染→子组件重渲染→状态更新」的无限循环,触发最大更新深度超限报错
  • 现有useEffect依赖为空,但内部用到了newData变量,属于遗漏依赖的写法,也会导致逻辑不符合预期
修复方案
  1. 把顶层的sessionStorage清理、初始数据getData的逻辑全部包裹在空依赖的useEffect里,保证只在组件首次挂载时执行一次
  2. 调整useEffect的依赖,把newData加入依赖数组,保证newData变更时才更新storeData的值
  3. 初始的newData状态类型改为对象,和表单返回的键值对结构匹配,避免逻辑异常
修复后完整代码
import { React, useEffect, useRef, useState } from "react";

import { globalFormStyling } from "../../../GlobalCommonStyling";
import { useHistory } from "react-router";
import { Navbar, SideBar } from "../../../../componenets/CommonComponents";
import JobForm from "../JobForm";
import { Grid } from "@material-ui/core";
import {
  FormInputButton,
  HollowButton,
} from "../../../../componenets/Theme/WebButtons";
import { jobEditedColumn } from "../JobValidation";

export default function EditJob(props) {
  let history = useHistory();
  const classes = globalFormStyling();
  const [newData, getNewData] = useState({}); // 初始值改为对象匹配表单结构
  const [getData, setGetData] = useState(null);
  const storeData = useRef(null);

  // 首次挂载执行的初始化逻辑,不会重复执行
  useEffect(() => {
    // 清理sessionStorage逻辑移到这里
    for (var i=0; i< sessionStorage.length; i++) {
      if(["JobInfo","EditJobFormVal","stateVars"].indexOf(sessionStorage.key(i))<0) {
        sessionStorage.removeItem(sessionStorage.key(i))
      }
    }
    // 读取初始表单数据逻辑移到这里
    let initialData;
    if(sessionStorage.getItem("JobInfo")) {
      initialData = JSON.parse(sessionStorage.getItem("JobInfo"))
    }else {
      initialData = props.location.state.inputData;
      sessionStorage.setItem("JobInfo", JSON.stringify(initialData));
    }
    setGetData(initialData);
    storeData.current = initialData;
  }, [props.location.state?.inputData]);

  // 新增依赖newData,只有newData变更才会更新ref的值
  useEffect(() => {
    if (!newData || !storeData.current) return;
    for (const [key] of Object.entries(newData)) {
      storeData.current[0][jobEditedColumn[key]] = newData[key];
    }
  }, [newData]);

  function onSuccess(isWarning)
  {
    sessionStorage.setItem("JobInfo", JSON.stringify(storeData.current));
    history.push("/SelfService/Jobs/JobInfo")
  }

  // 初始数据没加载完返回空,避免子组件接收到undefined报错
  if (!getData) return null;

  return (
    <div>
      <Navbar head={"Edit Job"} />
      <SideBar selected={7} />
      <div className={classes.gridLevelScreenDividing}>
        <div></div>
        <div>
          <JobForm marginTop="5.5%" minHeight="75%" existingDat={getData} getNewData={getNewData} onSuccess={onSuccess}/>
        </div>
        <div></div>
      </div>
      <div className={classes.bottomButtonStyling}>
        <Grid container>
          <Grid item sm={3} xs={1}>
            <div></div>
          </Grid>
          <Grid item container justify="center" spacing={3}>
            <Grid item>
              <HollowButton
                borderColor="black"
                inputWidth="136px"
                onClick={() => {
                  history.push("/SelfService/Jobs/JobInfo");
                }}
                style={{ marginTop: "13%" }}
              >
                Cancel
              </HollowButton>
            </Grid>
            <Grid item>
              <FormInputButton
                borderColor="black"
                inputWidth="136px"
                style={{ marginTop: "13%" }}
                type="submit"
                form={"jobDetailsForm"}
              />
            </Grid>
          </Grid>
          <Grid item sm={3} xs={1}>
            <div></div>
          </Grid>
        </Grid>
      </div>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:18:03