【问题标题】:Retrieve select value with redux-form使用 redux-form 检索选择值
【发布时间】:2017-03-16 22:13:20
【问题描述】:

我是一个初学者,所以不要被我的问题冒犯,这一定很愚蠢,但我已经卡了 2 长时间,尝试了很多我在搜索时发现的东西。

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

这是我的代码(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)

【问题讨论】:

    标签: reactjs redux react-redux redux-form


    【解决方案1】:

    您的问题很简单,您没有将任何内容绑定到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>);
    };
    

    希望这会有所帮助!

    【讨论】:

    • 确实!非常简单!我阻止了 redux-form 将 prop 传递给我的组件然后更改!因此,我更喜欢使用 {...field.input} 传递我的组件可能需要的所有输入信息 :) 非常感谢您的帮助!!!
    猜你喜欢
    • 2019-10-13
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多