web-dev-qa-db-fra.com

Comment créer un composant de champ déroulant personnalisé avec Redux-Form V6?

J'ai une application qui sera lourde de forme, et j'aimerais autant de contrôle que possible, tout en utilisant le moins de dépendances possible. Pour ce faire, je voudrais profiter de l'API de composant Field personnalisée de redux-form v6 et créer un tas de composants personnalisés que je peux déposer à volonté. L'un de ces composants est une liste déroulante.

Le problème est que le composant déroulant personnalisé ne se connecte pas à l'état, même s'il s'affiche correctement.

Dans les documents, les exemples accomplissent ceci comme:

<Field name="favoriteColor" component="select">
  <option></option>
  <option value="#ff0000">Red</option>
  <option value="#00ff00">Green</option>
  <option value="#0000ff">Blue</option>
</Field>

Je cherche une approche plug-and-play où je peux déposer un composant et alimenter les accessoires un tableau de données:

Form.js :

      <div className="form-group">
        <label htmlFor="dropDownSelect">Select an Option</label>
        <Field
          name="dropDownSelect"
          component={DropDownSelect}
          people={people}
          className="form-control"
        >
        </Field>
      </div>

DropDownSelect.js:

import React from 'react';

import styles from './styles.css';

class DropDownSelect extends React.Component { // eslint-disable-line react/prefer-stateless-function
  renderSelectOptions = (person) => {
    return (
      <option key={person} value={person}>{person}</option>
    );
  }

  render() {
    return (
      <select>
        {this.props.people.map(this.renderSelectOptions)}
      </select>
    );
  }
}


export default DropDownSelect;

Lorsque je vérifie Redux DevTools, la valeur du champ ne se remplit jamais lors de l'interaction avec la liste déroulante:

enter image description here

J'ai choisi une valeur pour les deux champs, mais seul "effDate" remplit une valeur, tandis que "dropDownSelect" reste un champ enregistré sans valeur.

Modifier:

Sur la base de l'exemple, je suppose que la façon de procéder est la suivante:

function DropDownSelect(person) {
  return (
    <option key={person} value={person}>{person}</option>
  );
}

export default DropDownSelect;


      <div className="form-group">
        <label htmlFor="dropDownSelect">Select an Option</label>
        <Field
          name="dropDownSelect"
          component="select"
          // component={DropDownSelect}
          // people={people}
          className="form-control"
        >
          {people.map(DropDownSelect)}
        </Field>

Cela fonctionne pour l'instant, mais ce serait idéal si je pouvais l'implémenter en tant que composant complètement séparé (comme indiqué dans la question initiale), afin que je puisse profiter des crochets du cycle de vie dans le cas où le champ dépendrait d'autres champs.

10
Kyle Truong

Pour faire un composant personnalisé séparé qui gère la liste déroulante, je devais inclure les accessoires `` d'entrée '' pour le connecter au réducteur de formulaire:

Composant personnalisé:

/**
*
* DropDownSelect
*
*/

import React from 'react';

import styles from './styles.css';

class DropDownSelect extends React.Component { // eslint-disable-line react/prefer-stateless-function

  renderSelectOptions = (person) => (
    <option key={person} value={person}>{person}</option>
  )

  render() {
    const { input, label } = this.props;
    return (
      <div>
        {/* <label htmlFor={label}>{label}</label> */}
        <select {...input}>
          <option value="">Select</option>
          {this.props.people.map(this.renderSelectOptions)}
        </select>
      </div>
    );
  }
}

// function DropDownSelect(person) {
//   return (
//     <option key={person} value={person}>{person}</option>
//   );
// }

DropDownSelect.propTypes = {
  people: React.PropTypes.array,
  input: React.PropTypes.object,
  label: React.PropTypes.string,
};

export default DropDownSelect;

Champ:

      <div className="form-group">
        <label htmlFor="dropDownSelect">Select an Option</label>
        <Field
          name="dropDownSelect"
          // component="select"
          label="dropDownSelect"
          component={DropDownSelect}
          people={people}
          className="form-control"
        >
          {/* {people.map(DropDownSelect)} */}
        </Field>
      </div>
14
Kyle Truong