web-dev-qa-db-fra.com

Redux Forms finit parfois par enregistrer / désinscrire une boucle infinie

J'ai du mal à apprivoiser les formulaires Redux.

J'ai le formulaire et les champs suivants. Ce qui semble fonctionner si j'ajoute simplement les données correctes et les soumets, mais si j'essaie de provoquer des erreurs de validation et de ressaisir les données plusieurs fois, cela finit parfois dans une boucle infinie.

La boucle infinie appelle action @@redux-form/REGISTER_FIELD et action @@redux-form/UNREGISTER_FIELD à plusieurs reprises et entraîne éventuellement l'erreur suivante.

Erreur non détectée: la profondeur de mise à jour maximale a été dépassée. Cela peut se produire lorsqu'un composant appelle à plusieurs reprises setState dans componentWillUpdate ou componentDidUpdate. React limite le nombre de mises à jour imbriquées pour éviter les boucles infinies.

Quelqu'un peut-il m'aider à comprendre ce qui pourrait causer cela et quelles mesures je peux prendre pour le faire fonctionner s'il vous plaît?

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

Ne faites pas ça:

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

chaque fois que le formulaire est rendu maxLength(5) construira une nouvelle fonction, ce qui provoquera un nouveau rendu du champ (parce que this.props.validate !== nextProps.validate)

Vous pouvez utiliser des instances spécifiquement définies de règles de validation paramétrées:

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