使用 redux-form 检索 select 值

Retrieve select value with redux-form

我是一个新手,所以不要被我的问题冒犯,这一定是一些愚蠢的东西,但我已经被困了 2 久,尝试了很多我在搜索时发现的东西。

我的问题非常简单,我将 React 和 redux 与 redux-form 库一起使用。我的表单非常简单,适用于所有字段,除了...我无法检索任何数据的组合框。就像我的 Field select 组件在我的 React 组件中不可见一样,它似乎不会对其状态等做出反应

这是我的代码(3 个不同的文件):

共享实用函数文件

export const renderSelectField = (field) => {
  var styles = {};
  var containerStyle = getInputStylesContainer();

  if (field.input.value || field.meta.touched) {
    if (!field.meta.error) {
      styles = getInputStylesSuccess();
      containerStyle = classNames(containerStyle, {'has-success': true});
    } else {
      styles = getInputStylesError();
      containerStyle = classNames(containerStyle, {'has-error': true});
    }
  }

  return (<div className={containerStyle}>
    {displayInputLabel(styles.idInput, field.label)}
    <select className='form-control' name={field.input.name} id={styles.idInput} aria-describedby={styles.ariaDescribedBy}>
      {field.options}
    </select>
    <span className={styles.glyphicon} aria-hidden='true' />
    {field.meta.touched && field.meta.error &&
    displayErrorMessage(field.meta.error)}
  </div>);
};

组件的容器

export class ProfileContainer extends React.Component {
  render () {
    // TODO: Check user connection (via the store or via a check within the cookie ?
    // TODO: Retrieve the proper userId (via mapStateToProps
    if (this.props.connected === false) browserHistory.push('/');
    return <ProfileForm
      user={this.props.user}
      fields={this.props.fields}
      errorMessage={this.props.errorMessage}
      confirmationMessage={this.props.confirmationMessage}
      onSubmitProfileUpdate={this.props.onSubmitProfileUpdate} />;
  }
}

ProfileContainer.propTypes = {
  user: React.PropTypes.object,
  connected: React.PropTypes.bool,
  fields: React.PropTypes.shape({
    email: React.PropTypes.string,
    firstname: React.PropTypes.string,
    lastname: React.PropTypes.string,
    ranking: React.PropTypes.string,
    telephone: React.PropTypes.string,
    city: React.PropTypes.string
  }),
  errorMessage: React.PropTypes.string,
  confirmationMessage: React.PropTypes.string,
  onSubmitProfileUpdate: React.PropTypes.func.isRequired
};

const mapStateToProps = (state) => {
  return {
    connected: state.userConnection.connection.connected,
    user: state.userConnection.loadProfile.user,
    errorMessage: state.profile.error,
    confirmationMessage: state.profile.confirmation
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    onSubmitProfileUpdate: (values) => {
      const user = {
        email: values.email,
        telephone: values.telephone,
        firstname: values.firstname,
        lastname: values.lastname,
        city: values.city,
        ranking: values.ranking
      };
      console.log(values);
      console.log('RANKING', user.ranking);
      dispatch(profileUpdate(user));
    }
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(ProfileContainer);

具有以下形式的组件

class ProfileForm extends React.Component {

  getTennisRankingsOptions (rankings) {
    return (
      tennisRankings.map(ranking =>
        <option value={ranking} key={ranking}>{ranking}</option>)
    );
  }
  render () {
    const { handleSubmit } = this.props;
    const messageClassname = this.props.errorMessage !== undefined ? stylesShared.errorMessage : this.props.confirmationMessage !== undefined ? stylesShared.confirmationMessage : '';
    return (
      <div>
        <div>
          <div>
            <form onSubmit={handleSubmit(this.props.onSubmitProfileUpdate)}>
              <div>
                <center><h4>Votre profil</h4></center>
              </div>
              <div className={messageClassname}>
                {this.props.errorMessage &&
                <span>{this.props.errorMessage}</span>
                }
                {this.props.confirmationMessage &&
                <span>{this.props.confirmationMessage}</span>
                }
              </div>
              <div>
                <Field name='firstname' type='text' label='Prénom' component={renderBasicField} />
              </div>
              <div>
                <Field name='lastname' type='text' label='Nom' component={renderBasicField} />
              </div>
              <div>
                <Field name='email' type='email' label='Email' component={renderEmailField} />
              </div>
              <div>
                <Field name='telephone' type='text' label='Téléphone' component={renderBasicField} />
              </div>
              <div>
                <Field name='ranking' className='input-row form-group form-control' options={this.getTennisRankingsOptions()} type='select' component={renderSelectField} />
              </div>
              <div>
                <Field name='city' type='text' label='Ville' component={renderBasicField} />
              </div>
              <div>
                <button className='btn btn-info btn-lg center-block' type='submit'>Mettre à jour</button>
              </div>
            </form>
          </div>
        </div>
      </div>
    );
  }
}

ProfileForm.propTypes = {
  user: React.PropTypes.object,
  fields: React.PropTypes.shape({
    firstname: React.PropTypes.string,
    lastname: React.PropTypes.string,
    email: React.PropTypes.string,
    telephone: React.PropTypes.string,
    ranking: React.PropTypes.string,
    city: React.PropTypes.string
  }),
  errorMessage: React.PropTypes.string,
  confirmationMessage: React.PropTypes.string,
  onSubmitProfileUpdate: React.PropTypes.func.isRequired,
  handleSubmit: propTypes.handleSubmit,
  initialize: propTypes.initialize
};

const validateProfileForm = values => {
  const errors = {};

  if (!values.firstname) errors.firstname = 'Un prénom est requis';
  else if (validator.isLength(values.firstname + '', {min: 0, max: 1})) errors.firstname = 'Votre prénom doit faire au moins 2 caractères';

  if (!values.lastname) errors.lastname = 'Un nom est requis';
  else if (validator.isLength(values.lastname + '', {min: 0, max: 1})) errors.lastname = 'Votre nom doit faire au moins 2 caractères';

  if (!values.email) errors.email = 'Un email est requis';
  else if (!validator.isEmail(values.email + '')) {
    errors.email = 'Adresse email invalide';
  }

  if (!values.telephone) errors.telephone = 'Un telephone est requis';
  else if (!validator.isMobilePhone(values.telephone + '', 'fr-FR')) {
    errors.telephone = 'Téléphone invalide';
  }

  if (!values.password) errors.password = 'Un mot de passe est requis';
  else if (validator.isLength(values.password + '', {min: 0, max: 4})) errors.password = 'Votre mot de passe doit faire au moins 5 caractères';

  return errors;
};

export default reduxForm({
  form: 'profile',
  validate: validateProfileForm
})(ProfileForm);

非常感谢你的帮助,我感到很绝望(我猜是菜鸟的通常感觉 X​​D)

您的问题很简单,您没有将任何内容绑定到 select 元素的 onChange 处理程序。一般取the onChange function provided as a prop by redux-form through the Field component.

即可

您可以这样做(删除部分代码以仅显示牛肉):

export const renderSelectField = (field) => {
  // *snip snip*
  return (
    <div className={containerStyle}>
      {displayInputLabel(styles.idInput, field.label)}
      <select className='form-control' name={field.input.name} 
        id={styles.idInput} aria-describedby={styles.ariaDescribedBy} 
        onChange={field.input.onChange}>
        {field.options}
      </select>
      <span className={styles.glyphicon} aria-hidden='true' />
      {field.meta.touched && field.meta.error &&
    displayErrorMessage(field.meta.error)}
    </div>);
};

希望对您有所帮助!