131 votes

React + Redux - Quelle est la meilleure façon de gérer CRUD dans un composant de formulaire?

J'en ai un formulaire qui est utilisé pour Créer, Lire, mettre à Jour et Supprimer. J'ai créé 3 pièces de la même forme, mais je les passent différents accessoires. J'ai eu CreateForm.js, ViewForm.js (readonly avec le bouton supprimer) et UpdateForm.js.

J'ai l'habitude de travailler avec PHP, donc je l'ai toujours fait dans un formulaire.

J'utilise Réagir et Redux pour gérer le magasin.

Quand je suis dans le CreateForm composant, je dois passer pour mon sous-composantes de ce accessoires createForm={true} de ne pas remplir les entrées d'une valeur et de ne pas les désactiver. Dans mon ViewForm composant, je passe cette props readonly="readonly".

Et j'ai eu un autre problème avec un textarea qui est rempli avec une valeur et n'est pas modifiable. Réagir textarea avec la valeur est en lecture seule, mais doivent être mis à jour

Quelle est la meilleure structure pour avoir un seul composant qui manipulent ces différents états de la forme?

Avez-vous des conseils, des tutoriels, des vidéos, des démos à partager?

115voto

Mike Boutin Points 428

J'ai trouvé le Redux Forme de package. Il fait un très bon travail!

Ainsi, vous pouvez utiliser Redux avec Réagissent-Redux.

Vous devez d'abord créer un formulaire composant (évidemment):

import React from 'react';
import { reduxForm } from 'redux-form';
import validateContact from '../utils/validateContact';

class ContactForm extends React.Component {
  render() {
    const { fields: {name, address, phone}, handleSubmit } = this.props;
    return (
      <form onSubmit={handleSubmit}>
        <label>Name</label>
        <input type="text" {...name}/>
        {name.error && name.touched && <div>{name.error}</div>}

        <label>Address</label>
        <input type="text" {...address} />
        {address.error && address.touched && <div>{address.error}</div>}

        <label>Phone</label>
        <input type="text" {...phone}/>
        {phone.error && phone.touched && <div>{phone.error}</div>}

        <button onClick={handleSubmit}>Submit</button>
      </form>
    );
  }
}

ContactForm = reduxForm({
  form: 'contact',                      // the name of your form and the key to
                                        // where your form's state will be mounted
  fields: ['name', 'address', 'phone'], // a list of all your fields in your form
  validate: validateContact             // a synchronous validation function
})(ContactForm);

export default ContactForm;

Après cela, vous vous connectez le composant qui s'occupe de la forme:

import React from 'react';
import { connect } from 'react-redux';
import { initialize } from 'redux-form';
import ContactForm from './ContactForm.react';

class App extends React.Component {

  handleSubmit(data) {
    console.log('Submission received!', data);
    this.props.dispatch(initialize('contact', {})); // clear form
  }

  render() {
    return (
      <div id="app">
        <h1>App</h1>
        <ContactForm onSubmit={this.handleSubmit.bind(this)}/>
      </div>
    );
  }

}

export default connect()(App);

Et d'ajouter que le redux-forme réducteur dans votre combiné réducteurs:

import { combineReducers } from 'redux';
import { appReducer } from './app-reducers';
import { reducer as formReducer } from 'redux-form';

let reducers = combineReducers({
  appReducer, form: formReducer // this is the form reducer
});

export default reducers;

Et le validateur module ressemble à ceci:

export default function validateContact(data, props) {
  const errors = {};
  if(!data.name) {
    errors.name = 'Required';
  }
  if(data.address && data.address.length > 50) {
    errors.address = 'Must be fewer than 50 characters';
  }
  if(!data.phone) {
    errors.phone = 'Required';
  } else if(!/\d{3}-\d{3}-\d{4}/.test(data.phone)) {
    errors.phone = 'Phone must match the form "999-999-9999"'
  }
  return errors;
}

Une fois le formulaire rempli, lorsque vous voulez remplir tous les champs avec des valeurs, vous pouvez utiliser l' initialize fonction de:

componentWillMount() {
  this.props.dispatch(initialize('contact', {
    name: 'test'
  }));
}

Je recherche maintenant pour savoir comment rendre les champs en mode lecture seule ou handicapées... Si vous avez obtenu une autre façon de gérer cela, il suffit de laisser un message! Je vous remercie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X