IssaChii
IssaChii

Reputation: 65

React: react-datepicker won't update state

I am trying to do on change on datepicker, but the state doesn't update. I am using a state from props. So the date already exists. It shows expired dates. When I am doing the on change, it get stuck at the current date.

Something I am missing in the onChange handler?

  constructor(props) {
    super(props);

    const {export} = this.props;
    this.state = {showCalender: false};
    this.date = export.expires;

    this.handleChange = this.handleChange.bind(this);
  }

  static getDerivedStateFromProps(props, state) {
    if (props.export.expires !== state.expires) {
      return {
        expires: props.export.expires
      };
    }
    return null;
  }

  handleChange(date) {
    this.setState({
      expires: date
    }, console.log(this.state.expires));
    this.handleClick();
  }

  handleClick() {
    this.setState({showCalender: !this.state.showCalender});
  }

  handleClear() {
    this.setState({expires: ''});
  }

  render() {
    const {expires, showCalender} = this.state;
    const expiresDate = format(expires, 'MM/dd/yyyy');

    return (
        <div>
          <FormGroup>
            <FormControl
              id="date"
              value={expiresDate}
              onChange={this.handleChange}
              onClick={() => this.handleClick()}
              title="set date"
              aria-label="set date"
            />
            <Button className="close-btn" onClick={() => this.handleClear()}>Clear</Button>
          </FormGroup>
          { showCalender && (
            <FormGroup>
              <DatePicker
                selected={expires}
                onChange={this.handleChange}
                inline
              />
            </FormGroup>
          )}
      </div>
    );
  }

Upvotes: 1

Views: 730

Answers (1)

Sagiv b.g
Sagiv b.g

Reputation: 31024

When you update the state you are triggering a re-render, but just before the next render, react is calling the getDerivedStateFromProps which there you are checking to see if the values are different:

static getDerivedStateFromProps(props, state) {
    if (props.export.expires !== state.expires) {
      return {
        expires: props.export.expires
      };
    }
    return null;
  }

Which they are, as you just updated the state but the props stayed the same. And then you update the state again but now you set it back to whatever the value in props is.

From the DOCS:

getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates.

I'm not sure why you are trying to sync props and state, but usually this indicates a bad design of your app.

As mentioned in the comments, do not use a variable named export as its a reserved word since ES2015.

You might get an error of:

Unexpected keyword 'export'

Upvotes: 1

Related Questions