我正试图获得依赖于下拉值选择的validate redux表单,下面是代码和错误。
我得到的是Uncaught Error: Maximum update depth exceeded.
当组件在componentWillUpdate
或componentDidUpdate
内重复调用setState时,可能会发生这种情况。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)
您不应该在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所指出的,在render中调用的任何函数(如userRoleSelectField
、emailField
或emailRequiredForAdminValidator
…(,如果导致另一个render,例如通过调用setState
,都会导致调用堆栈溢出。
我同意Nitin Garg的观点。在为组件属性赋值时,不应调用函数。如果需要调用,可以使用箭头函数。
validate={[emailRequiredForAdmin("role")]}
成为
validate={[() => { emailRequiredForAdmin("role"); } ]}