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

实现redux-form下拉依赖校验时触发Maximum update depth exceeded错误如何解决

问题原因

你的代码触发无限循环的核心原因有三个:

  1. HOC包裹顺序错误:你先给组件套了reduxForm,再套connect,redux-form的状态更新会触发外层connect重新计算返回新props,导致表单组件重渲染,重渲染又触发redux-form的状态校验更新,形成死循环。redux-form官方要求的HOC执行顺序是先执行connect,再套reduxForm。
  2. 内联函数导致不必要重渲染:role字段的Field组件直接传入了内联箭头函数作为onChange,每次组件渲染都会生成新的函数引用,触发Field组件重复渲染,进一步加剧循环。
  3. 多余的表单值更新:你在role的onChange回调里,只要选中user角色就强制修改密码和确认密码为空,哪怕这两个字段已经是空值,也会触发redux-form状态更新,加大循环概率。
修复步骤

1. 调整HOC包裹顺序

把connect逻辑放到reduxForm包裹之前:

const selector = formValueSelector(formNames.USER);
// 先做connect
const ConnectedUsersForm = connect((state) => {
  const selectedRole = selector(state, "role");
  return {
    selectedRole,
  };
})(UsersForm);

// 再套reduxForm
UsersForm = reduxForm({
  form: formNames.USER,
})(ConnectedUsersForm);

2. 提取内联onChange为类方法

把onChange逻辑从Field的props里提取为组件的实例方法,避免每次渲染生成新的函数引用,同时加判断避免不必要的表单值修改:

// 组件内部定义方法(类属性写法,不用额外bind)
handleRoleChange = (event) => {
  const { change, password, confirmPassword } = this.props;
  // 只有角色是user,且密码字段不为空的时候才执行修改
  if (event.target.value === "user" && (password !== "" || confirmPassword !== "")) {
    change("password", "");
    change("confirmPassword", "");
  }
}

// Field组件引用方法
<Field
  id="user-form-roles"
  name="role"
  component={userRoleSelectField}
  className={style.inputField}
  fullWidth={true}
  items={getRoles(intl)}
  label={i18n({ id: "users.role" })}
  onChange={this.handleRoleChange}
/>

3. 可选优化

如果你的emailRequiredForAdmin("role")是工厂函数,每次执行都会生成新的校验函数,建议把生成的校验函数提取到组件外部,或者存在组件实例属性上,避免每次渲染都传递新的validate数组触发Field重复渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 02:24:03