使用 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);
非常感谢你的帮助,我感到很绝望(我猜是菜鸟的通常感觉 XD)
您的问题很简单,您没有将任何内容绑定到 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>);
};
希望对您有所帮助!
我是一个新手,所以不要被我的问题冒犯,这一定是一些愚蠢的东西,但我已经被困了 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);
非常感谢你的帮助,我感到很绝望(我猜是菜鸟的通常感觉 XD)
您的问题很简单,您没有将任何内容绑定到 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>);
};
希望对您有所帮助!