设置状态

时间:2018-05-25 20:23:10

标签: javascript forms reactjs redux immutability

我有一个DayPicker组件,允许用户选择多个日期。我将此数据存储在Date个对象的数组中,当用户在多步骤表单中单击下一个时,该对象将被发送到reducer。但是,如果我返回此表单,我无法添加和删除任何日期。这就是我的组件的样子

    class StepThree extends Component {
  static getDerivedStateFromProps = (nextProps) => {
    const {
      stepThree: { dates }
    } = nextProps;
    const shouldUpdate = dates.length !== 0;
    if (shouldUpdate) {
      const newDates = dates.map(date => new Date(date));
      return {
        dates: newDates
      };
    }
    return null;
  };

  state = {
    dates: []
  };

  handleDayClick = (day, { selected }) => {
    const { dates } = this.state;
    if (selected) {
      const selectedIndex = dates.findIndex(selectedDay => DateUtils.isSameDay(selectedDay, day));
      dates.splice(selectedIndex, 1);
    } else {
      dates.push(day);
    }
    this.setState({ dates });
  };

  handleNext = (e) => {
    e.preventDefault();
    this.props.setStepThree(this.state.dates);
  };

  render() {
    return (
      <Col>
        <Col style={{ textAlign: 'center' }}>
          <DayPicker selectedDays={this.state.dates} onDayClick={this.handleDayClick} />
        </Col>
        <div
          style={{
            width: '100%',
            position: 'fixed',
            bottom: '0px',
            zIndex: '100',
            textAlign: 'center',
            padding: '10px',
            left: '0px'
          }}
        >
          <PreviousButton handleClick={this.props.handlePrevious} />
          <NextButton handleClick={this.handleNext} />
        </div>
      </Col>
    );
  }
} 

当我返回到此表单时,我看到新日期被传递到handleClick方法,但它不会附加到数组。国家仍然是名字。

注意:这是用户第一次填写表单后的可重现模式。在第一次之后,这基本上是不可编辑的。

这是减速器代码

    case ACTIONS.SET_STEP_THREE: {
        const newDates = action.dates.map(d => new Date(d));
        return {
          ...state,
          stepThree: {
            ...state.stepThree,
            dates: newDates
        }
     };
   }

1 个答案:

答案 0 :(得分:0)

在日期数组中推送或删除日期不会更改其引用。您应该重新创建日期数组以更新其引用,并允许您检测组件状态的变化。您可以使用任何方法重新创建日期数组exp:array.concatarray.slice或Spread语法let newDatesRf = [...dates];

handleDayClick = (day, { selected }) => {
   const { dates } = this.state;
   if (selected) {
     const selectedIndex = dates.findIndex(selectedDay => 
        DateUtils.isSameDay(selectedDay, day));
     dates.splice(selectedIndex, 1);
   } else {
    dates.push(day);
   }
   let newDatesRf = [...dates];//copy dates array to a new array
   this.setState({ dates:newDatesRf });
};