Reactjs 处理带<;的出生日期;选择>;redux形式的字段

Reactjs 处理带<;的出生日期;选择>;redux形式的字段,reactjs,redux,redux-form,Reactjs,Redux,Redux Form,我正在使用一个用户注册表格 对于表单的出生日期部分,我有一个日期、月份和年份的字段 到目前为止,我一直在使用redux表单的字段组件将日、月和年作为单独的变量进行捕获: const dobSelects = fields => { const { label, input } = fields; return ( <div> <label>{label}</label> <select {...fields.

我正在使用一个用户注册表格

对于表单的出生日期部分,我有一个日期、月份和年份的
字段

到目前为止,我一直在使用
redux表单的
字段
组件
将日、月和年作为单独的变量进行捕获:

const dobSelects = fields => {
  const { label, input } = fields;
  return (
    <div>
      <label>{label}</label>
      <select {...fields.day.input} name="dob" id="">
        <option />
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
      </select>
      <select {...fields.month.input} id="">
        <option />
        <option value="january">January</option>
        <option value="february">February</option>
        <option value="march">March</option>
      </select>
      <select {...fields.year.input} id="">
        <option />
        <option value="2000">2000</option>
        <option value="2001">2001</option>
        <option value="2002">2002</option>
      </select>
    </div>
  );
};
但是,如果我想发送一个字段作为
日期
对象,而不是三个单独的字段,同时保持相同的用户界面,该怎么办

我希望用户选择这三个字段,而不是发送三个单独的字段,而是发送一个
dateOfBirth
字段作为
Date
对象

此外,在这种情况下,redux表单的
字段
组件似乎不够,因为我无法将
验证
道具传递给它以验证出生日期;我需要将这三个字段作为一个字段进行验证,而不是单独进行验证


如何使用redux表单实现这一点?

不使用
字段组件创建自定义字段。以下是总体思路:

class DOBSelects extends React.Component {
    constructor(props) {
        super(props);
        this.state = this.buildState(props.input.value)
    }

    componentWillReceiveProps(props) {
        if(props.input.value !== this.props.input.value) {
            this.setState(this.buildState(props.input.value));
        }
    }

    buildState(value) {
        return value ? { 
            date: value.getDate(), 
            month: value.getMonth() + 1, year: 
            value.getFullYear()
        } : {
            date: '',
            month: '',
            year: ''
        }
    }

    update(state) {
        this.setState(state);

        const { date, month, year } = { ...this.state, ...state };
        const { onChange, value } = this.props.input;

        if(date && month && year) {
            onChange(new Date(year, month - 1, date));
        } else if(value) {
            onChange(null);
        }
    }

    render () {
        const { label, input: { name } } = this.props;
        const { date, month, year } = this.state
        const thisYear = new Date().getFullYear();

        return (
        <div>
            <label htmlFor={name + '-day'}>
                {label}
            </label>
            <select onChange={e => { this.update({ date: e.target.value }); }} value={date} name={name + '-day'}>
                <option />
                {getOptions(1, 31)}
            </select>
            <select onChange={e => this.update({ month: e.target.value })} value={month} name={name + '-month'}>
                <option />
                {getOptions(1, 12)}
            </select>
            <select onChange={e => this.update({ year: e.target.value })} value={year} name={name + '-year'}>
                <option />
                {getOptions(thisYear - 20, thisYear)}
            </select>
        </div>
    );
  };
}

function getOptions(start, end) {
    const options = [];

    for(let i = start; i <= end; i++) {
        options.push(<option key={i}>{i}</option>)
    }

    return options;
}
class.Component{
建造师(道具){
超级(道具);
this.state=this.buildState(props.input.value)
}
组件将接收道具(道具){
if(props.input.value!==this.props.input.value){
this.setState(this.buildState(props.input.value));
}
}
buildState(值){
返回值?{
日期:value.getDate(),
月份:value.getMonth()+1,年份:
value.getFullYear()
} : {
日期:'',
月份:'',
年份:''
}
}
更新(状态){
本.设置状态(状态);
const{date,month,year}={…this.state,…state};
const{onChange,value}=this.props.input;
如果(日期、月份和年份){
变更(新日期(年,月-1,日期));
}else if(值){
onChange(空);
}
}
渲染(){
const{label,输入:{name}}=this.props;
const{date,month,year}=this.state
const thiswear=新日期().getFullYear();
返回(
{label}
{this.update({date:e.target.value});}}value={date}name={name+'-day'}>
{getOptions(1,31)}
this.update({month:e.target.value})value={month}name={name+'-month'}>
{getOptions(1,12)}
this.update({year:e.target.value})value={year}name={name+'-year'}>
{getOptions(今年-20,今年)}
);
};
}
函数getOptions(开始、结束){
常量选项=[];

对于(let i=start;i这看起来是一个很好的解决方案。但是,为日期对象提供验证似乎仍然是一个问题。我希望等到用户在所有三个字段中输入数据后,数据才会变脏。
脏。
。据我所知,使用redux表单无法实现这一点。您需要使用有状态组件为了实现这一点,我更新了答案以进行演示。日期选择器不是一个好的出生日期用户体验。对于一岁以上的人来说,需要太多的导航。对于一年来说,下拉列表也不太好,除非预期的用户组的年龄范围非常窄。
class DOBSelects extends React.Component {
    constructor(props) {
        super(props);
        this.state = this.buildState(props.input.value)
    }

    componentWillReceiveProps(props) {
        if(props.input.value !== this.props.input.value) {
            this.setState(this.buildState(props.input.value));
        }
    }

    buildState(value) {
        return value ? { 
            date: value.getDate(), 
            month: value.getMonth() + 1, year: 
            value.getFullYear()
        } : {
            date: '',
            month: '',
            year: ''
        }
    }

    update(state) {
        this.setState(state);

        const { date, month, year } = { ...this.state, ...state };
        const { onChange, value } = this.props.input;

        if(date && month && year) {
            onChange(new Date(year, month - 1, date));
        } else if(value) {
            onChange(null);
        }
    }

    render () {
        const { label, input: { name } } = this.props;
        const { date, month, year } = this.state
        const thisYear = new Date().getFullYear();

        return (
        <div>
            <label htmlFor={name + '-day'}>
                {label}
            </label>
            <select onChange={e => { this.update({ date: e.target.value }); }} value={date} name={name + '-day'}>
                <option />
                {getOptions(1, 31)}
            </select>
            <select onChange={e => this.update({ month: e.target.value })} value={month} name={name + '-month'}>
                <option />
                {getOptions(1, 12)}
            </select>
            <select onChange={e => this.update({ year: e.target.value })} value={year} name={name + '-year'}>
                <option />
                {getOptions(thisYear - 20, thisYear)}
            </select>
        </div>
    );
  };
}

function getOptions(start, end) {
    const options = [];

    for(let i = start; i <= end; i++) {
        options.push(<option key={i}>{i}</option>)
    }

    return options;
}