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

Sar*_*oma 11 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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

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>
);
Run Code Online (Sandbox Code Playgroud)

Igo*_*sow 24

不要这样做:

validate={[isRequired, maxLength(5)]}
Run Code Online (Sandbox Code Playgroud)

每次渲染表单时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]}
/>
Run Code Online (Sandbox Code Playgroud)

  • 我必须在render()之外定义函数 (5认同)
  • @igor,你今晚拯救了我的心理健康! (2认同)