Reactjs 使用redux表单检索select值
我是一个新手,所以不要被我的问题激怒,这一定是愚蠢的事情,但我已经被困了2个长时间,尝试了这么多我在搜索时发现的东西 我的问题非常简单,我使用React和redux以及redux表单库。我的表单非常简单,适用于所有字段,除了。。。我的组合框无法检索任何数据。这就像我的字段选择组件在我的react组件中不可见一样,该组件似乎不会对其状态做出反应,等等 这是我的代码(3个不同的文件): 共享实用程序功能文件Reactjs 使用redux表单检索select值,reactjs,redux,react-redux,redux-form,Reactjs,Redux,React Redux,Redux Form,我是一个新手,所以不要被我的问题激怒,这一定是愚蠢的事情,但我已经被困了2个长时间,尝试了这么多我在搜索时发现的东西 我的问题非常简单,我使用React和redux以及redux表单库。我的表单非常简单,适用于所有字段,除了。。。我的组合框无法检索任何数据。这就像我的字段选择组件在我的react组件中不可见一样,该组件似乎不会对其状态做出反应,等等 这是我的代码(3个不同的文件): 共享实用程序功能文件 export const renderSelectField = (field) =>
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 const renderSelectField=(field)=>{
var样式={};
var containerStyle=getInputStylesContainer();
if(field.input.value | | field.meta.toucted){
如果(!field.meta.error){
styles=GetInputStylesAccess();
containerStyle=classNames(containerStyle,{'has-success':true});
}否则{
styles=getInputStylesError();
containerStyle=classNames(containerStyle,{'has-error':true});
}
}
返回(
{displayInputLabel(styles.idInput,field.label)}
{field.options}
{field.meta.com&&field.meta.error&&
displayErrorMessage(field.meta.error)}
);
};
组件的容器
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);
导出类ProfileContainer扩展React.Component{
渲染(){
//TODO:检查用户连接(通过商店还是通过cookie中的检查?
//TODO:检索正确的用户ID(通过MapStateTops)
如果(this.props.connected==false)browserHistory.push('/');
返回;
}
}
ProfileContainer.propTypes={
用户:React.PropTypes.object,
已连接:React.PropTypes.bool,
字段:React.PropTypes.shape({
电子邮件:React.PropTypes.string,
名字:React.PropTypes.string,
lastname:React.PropTypes.string,
排名:React.PropTypes.string,
电话:React.PropTypes.string,
城市:React.PropTypes.string
}),
errorMessage:React.PropTypes.string,
确认消息:React.PropTypes.string,
onSubmitProfileUpdate:React.PropTypes.func.isRequired
};
常量mapStateToProps=(状态)=>{
返回{
已连接:state.userConnection.connection.connected,
用户:state.userConnection.loadProfile.user,
errorMessage:state.profile.error,
确认消息:state.profile.confirmation
};
};
const mapDispatchToProps=(调度)=>{
返回{
onSubmitProfileUpdate:(值)=>{
常量用户={
电子邮件:values.email,
电话,
firstname:values.firstname,
lastname:values.lastname,
城市:价值观,城市,
排名:价值
};
console.log(值);
console.log('RANKING',user.RANKING);
分派(档案更新(用户));
}
};
};
导出默认连接(
MapStateTops,
mapDispatchToProps
)(集装箱);
具有表单的组件
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);
class ProfileForm扩展了React.Component{
getTennisRankingsOptions(排名){
返回(
tennisRankings.map(排名=>
{排名})
);
}
渲染(){
const{handleSubmit}=this.props;
const messageClassname=this.props.errorMessage!==未定义?stylesShared.errorMessage:this.props.confirmationMessage!==未定义?stylesShared.confirmationMessage:“”;
返回(
Votre profil
{this.props.errorMessage&&
{this.props.errorMessage}
}
{this.props.confirmationMessage&&
{this.props.confirmationMessage}
}
梅特雷日
);
}
}
ProfileForm.propTypes={
用户:React.PropTypes.object,
字段:React.PropTypes.shape({
名字:React.PropTypes.string,
lastname:React.PropTypes.string,
电子邮件:React.PropTypes.string,
电话:React.PropTypes.string,
排名:React.PropTypes.string,
城市:React.PropTypes.string
}),
errorMessage:React.PropTypes.string,
确认消息:React.PropTypes.string,
onSubmitProfileUpdate:React.PropTypes.func.isRequired,
handleSubmit:propTypes.handleSubmit,
初始化:propTypes.initialize
};
const validateProfileForm=值=>{
常量错误={};
如果(!values.firstname)errors.firstname='Un prénom est requires';
else if(validator.isLength(values.firstname+“”,{min:0,max:1}))errors.firstname='Votre prénom doit faire au moins 2克拉';
如果(!values.lastname)errors.lastname='Un nom est requires';
else if(validator.isLength(values.lastname+“”,{min:0,max:1}))errors.lastname='Votre nom doit faire au moins 2克拉';
如果(!values.email)errors.email='Un email est requires';
如果(!validator.isEmail(values.email+''),则为else{
errors.email='Adresse email invalide';
}
如果(!values.telephone)errors.telephone='Un telephone est requires';
否则如果(!validator.isMobilePhone(values.telephone+“”,'fr')){
errors.telephone='Téléphone invalide';
}
如果(!values.password)errors.password='Un mot de passe est requires';
else if(validator.isLength(values.password+“”,{min:0,max:4}))errors.password='Votre mot de passe doit fair au moins 5克拉';
返回错误;
};
导出默认reduxForm({
表格:'profile',
验证:validateProfileForm
})(档案格式);
非常感谢你的帮助,我感觉很绝望(我想我通常是想找个傻瓜)你的问题很简单,
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>);
};