5

我正在尝试根据下拉值选择来验证 redux-form,下面是代码和错误。

Uncaught Error: Maximum update depth exceeded.当组件在内部重复调用setStatecomponentWillUpdatecomponentDidUpdate. React 限制了嵌套更新的数量以防止无限循环。

请帮助我并提前致谢

    ...
      <Field
        id="user-form-email"
        name="email"
        component={emailField}
        className={style.inputField}
        fullWidth
        label={i18n({ id: "users.email" })}
        validate={[emailRequiredForAdmin("role")]}
        disabled={selectedRole === "manager"}
      />

      <Field
        id="user-form-roles"
        name="role"
        component={userRoleSelectField}
        className={style.inputField}
        fullWidth={true}
        items={getRoles(intl)}
        label={i18n({ id: "users.role" })}
        onChange={(event) => {
          if (event.target.value == "user") {
            this.props.change("password", "");
            this.props.change("confirmPassword", "");
          }
        }}
      />
    ...

// Decorate with redux-form

UsersForm = reduxForm({
  form: formNames.USER,
})(UsersForm);

const selector = formValueSelector(formNames.USER);

UsersForm = connect((state) => {
  const selectedRole = selector(state, "role");
  return {
    selectedRole,
  };
});

错误:

    The above error occurred in the <Form(Connect(UsersForm))> component:
    in Form(Connect(UsersForm)) (created by ConnectFunction)
    in ConnectFunction (created by Connect(Form(Connect(UsersForm))))
    in Connect(Form(Connect(UsersForm))) (created by ReduxForm)
    in ReduxForm (created by Context.Consumer)
    in Hoc (created by ReduxForm)
    in ReduxForm (created by ConnectFunction)
    in ConnectFunction (created by Users)
    in Users (created by ConnectFunction)
    in ConnectFunction (created by _temp)
    in _temp (created by Context.Consumer)
    in Route (created by App)
    in Switch (created by App)
    in div (created by RoutesContainer)
    in RoutesContainer (created by App)
    in div (created by Container)
    in Container (created by App)
    in div (created by Layout)
    in Layout (created by App)
    in div (created by App)
    in App (created by Context.Consumer)
    in Route (created by RootApp)
    in Switch (created by RootApp)
    in MuiPickersUtilsProvider (created by RootApp)
    in ThemeProvider (created by RootApp)
    in Router (created by ConnectedRouter)
    in ConnectedRouter (created by Context.Consumer)
    in ConnectedRouterWithContext (created by ConnectFunction)
    in ConnectFunction (created by RootApp)
    in Provider (created by RootApp)
    in RootApp (created by LocalizedApp)
    in IntlProvider (created by LocalizedApp)
    in LocalizedApp

    Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
        at checkForNestedUpdates (react-dom.development.js:23093)
        at scheduleUpdateOnFiber (react-dom.development.js:21164)
        at dispatchAction (react-dom.development.js:15660)
        at Subscription.checkForUpdates (connectAdvanced.js:101)
        at Subscription.handleChangeWrapper (Subscription.js:100)
        at eval (Subscription.js:26)
        at batchedUpdates$1 (react-dom.development.js:21856)
        at Object.notify (Subscription.js:22)
        at Subscription.notifyNestedSubs (Subscription.js:95)
        at Subscription.checkForUpdates (connectAdvanced.js:90)
4

2 回答 2

1

您不应该在 validate 数组中调用函数。改为这样做。

    // Outside of the component, if possible: 
    const emailRequiredForAdminValidator = emailRequiredForAdmin("role")

    // Or useMemo if you need component state, and you have to put any
    // value used in the `emailRequiredForAdmin` in that `useMemo` deps array
    const emailRequiredForAdminValidator = useMemo(() => 
      emailRequiredForAdmin("role")
    , [/* deps here */]);
    
    <Field
        id="user-form-email"
        name="email"
        component={emailField}
        className={style.inputField}
        fullWidth
        label={i18n({ id: "users.email" })}
        validate={[emailRequiredForAdminValidator]}
        disabled={selectedRole === "manager"}
      />

这是因为每次重新渲染组件时都会再次调用函数 userRoleSelectField,这会导致组件再次重​​新渲染,从而导致无限循环。

基本上,正如@diedu 所指出的,在渲染时调用的任何函数(例如userRoleSelectFieldemailFieldemailRequiredForAdminValidator...)并导致另一个渲染,例如通过调用setState,将导致调用堆栈溢出。

于 2021-05-24T09:40:53.273 回答
-1

我同意尼廷·加格的观点。分配给组件属性时不应调用函数。如果你需要打电话,你可以使用箭头功能。

validate={[emailRequiredForAdmin("role")]}

变成

validate={[() => { emailRequiredForAdmin("role"); } ]}
于 2021-05-27T02:30:37.407 回答