web-dev-qa-db-ja.com

Reduxフォームが登録/登録解除の無限ループになることがある

Redux Formsを使いこなすのに問題があります。

以下のフォームとフィールドがあります。正しいデータを追加して送信するとうまくいくようですが、検証エラーを発生させてデータを数回再入力しようとすると、無限ループになることがあります。

無限ループがaction @@redux-form/REGISTER_FIELDおよびaction @@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>
);
13
Sarcoma

これを行わないでください:

_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]}
/>
_
22
Igor Alemasow