简体   繁体   中英

react date array not updating after setting state

I have a DayPicker component that allows a user to select multiple dates. I store this data in an array of Date objects that gets sent to the reducer when the user clicks next in a multistep form. However, if I return back to this form, I cannot add AND remove any dates. This is what my component looks like

    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>
    );
  }
} 

When I return to this form, I see the new date being passed into the handleClick method, but it does not append to the array. The state remains the name.

NOTE: This is a reproducible pattern after the first time the user has filled the form. After the first time, this is basically uneditable.

This is the reducer code

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

Pushing or removing date to/ from dates array will not change its reference. you should recreate the dates array to update its reference and allow react to detect the changes of the component state. you can use any method to recreate the dates array exp : array.concat or array.slice or the Spread syntax 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 });
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM