Redux Forms有时会以注册/注销无限循环结束

时间:2018-07-16 18:46:05

标签: reactjs redux redux-form

我无法驯服Redux Forms。

我有以下表格和字段。如果我只是添加正确的数据并提交,那似乎可行,但是如果我尝试导致验证错误并重新输入数据几次,有时会陷入无限循环。

无限循环反复调用action @@redux-form/REGISTER_FIELDaction @@redux-form/UNREGISTER_FIELD,最终导致以下错误。

  

未捕获的错误:超出最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,可能会发生这种情况。 React限制了嵌套更新的数量,以防止无限循环。

请问有人可以帮助我了解造成此问题的原因以及可以采取哪些步骤使其正常工作吗?

ContactPage.js

import React, {Component} from 'react';
import ContactForm from './contact-form';

class ContactPage extends Component {
    submit = values => {
        console.log(values);
    };

render() {
    return (
        <div>
            <ContactForm onSubmit={this.submit}/>
        </div>
    );

    }
}

export default ContactPage;

ContactForm.js

import React from 'react';
import {Field, reduxForm} from 'redux-form';
import {isEmail, isRequired, maxLength} from '../validation';
import {Input, Select, TextArea} from './form-elements';

let ContactForm = ({handleSubmit}) =>
    <form onSubmit={handleSubmit}>
        <div>
            <Field name="fullname"
                   label="Full Name"
                   component={Input}
                   type="text"
                   validate={[isRequired, maxLength(5)]}
            />
        </div>
        <div>
            <Field name="email" component={Input} type="email"
                   validate={[isRequired, maxLength(254), isEmail]}
                   classes={['email-field']}
            />
        </div>
        <div>
            <Field name="message" component={TextArea}
                   validate={[isRequired]}
            />
        </div>
        <button type="submit">Submit</button>
    </form>
;

ContactForm = reduxForm({
    form: 'contact'
})(ContactForm);

export default ContactForm;

FormElements.js

import React from 'react';

const Label = ({label, forName}) => <label htmlFor={forName} className="form-label">{label}</label>;

export const Input = ({input, label, type, classes = [], meta: {touched, error}}) => (
    <div className={['form-field', 'input', ...classes].join(' ')}>
        <Label label={label} forName={input.name}/>
        <div>
            <input {...input} type={type} placeholder={label}
                   className={['form-input', touched && error ? 'form-error' : ''].join(' ')}/>
            {touched && error && <p className='form-error'>{error}</p>}
        </div>
    </div>
);

export const TextArea = ({input, label, classes = [], meta: {touched, error}}) => (
    <div className={['form-field', 'text-area', ...classes].join(' ')}>
        <Label label={label} forName={input.name}/>
        <div>
            <textarea {...input} placeholder={label} className={[touched && error ? 'form-error' : ''].join(' ')}/>
            {touched && error && <p className='form-error'>{error}</p>}
        </div>
    </div>
);

2 个答案:

答案 0 :(得分:17)

不要这样做:

validate={[isRequired, maxLength(5)]}

每次呈现表单maxLength(5)都会构造一个新函数,这将导致字段重新呈现(因为this.props.validate !== nextProps.validate

您可以使用专门定义的参数化验证规则实例:

const maxLength = max => value =>
    value && value.length > max ? `Must be ${max} characters or less` : undefined;
const maxLength15 = maxLength(15);

<Field
    name="username"
    type="text"
    component={renderField}
    label="Username"
    validate={[required, maxLength15]}
/>

答案 1 :(得分:0)

我遇到了同样的问题。 validate={[isRequired, maxLength(5)]} 没有帮助。发现在我的组件中是

useEffect(() => {
   dispatch(reset('myForm'));
}, [])

帮助

useEffect(() => {
    return dispatch(reset('myForm'));
}, [])