Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is concat on array inside this.state not working?

Tags:

reactjs

I'm trying to add rendered dates inside of my array located in my component state under the key date, but it always returns 0.

constructor(props) {
    super(props);
    this.state = {
      dates: []
    }
  }

  componentWillMount() {
    this.renderDateComp()
  }

  renderDateComp() {
    for(var i = 0; i < 5; i++) {
      var dat = new Date(Date().valueOf());
      dat.setDate(dat.getDate() + i);
      this.setState({ dates: this.state.dates.concat(dat) });
      console.log(this.state.dates); //prints length of 0
    }
  }
like image 903
joethemow Avatar asked Nov 25 '25 12:11

joethemow


2 Answers

Well firstly, state transitions aren't immediate, they are asynchronous (in most circumstances). Think of it like every time you set the state, it adds that state change to a queue of changes and React is continuously working through that queue, doing all those state changes. So if you change the state, then on the next line of code immediately print the state, the state probably won't have changed because the console.log happens IMMEDIATELY after the state change is added to the list, but BEFORE the change has actually gone through that queue.

Secondly, it's probably better to set the state AFTER the for loop, so you only have to set it once, not 5 times.

like image 132
Jayce444 Avatar answered Nov 28 '25 03:11

Jayce444


The recommended way to do it would be to:

  1. Call setState only once after you have the final dates array.
  2. Log this.state.dates in the callback of setState (it will only be called after this.state has been properly updated by React.

The key point to note here is that setState is asynchronous. You probably do not need to console.log the array in your real code.

Read more about setState here.

constructor(props) {
  super(props);
  this.state = {
    dates: []
  }
}

componentWillMount() {
  this.renderDateComp()
}

renderDateComp() {
  var dates = this.state.dates;
  for (var i = 0; i < 5; i++) {
    var dat = new Date(Date().valueOf());
    dat.setDate(dat.getDate() + i);
    dates = dates.concat(dat);
  }
  this.setState({ 
    dates
  }, () => {
    console.log(this.state.dates); //prints length of 5
  });
}
like image 41
Yangshun Tay Avatar answered Nov 28 '25 01:11

Yangshun Tay



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!