title: react setstate not working when pushing elements to array
body: <p>I am trying to push elements to an array of objects in the component state (in react.js), i am calling the method Array.concat wich returns a new array. </p>
  
  <pre><code>pushDeck(id, name) {
    var newDeck = [{
      id: id,
      name: name
    }];
    console.log("new path should be: ", this.state.path.concat(newDeck));
    this.setState({
      path: this.state.path.concat(newDeck)
    }, () =&gt; {
      console.log("setstate callback: ", this.state.path);
    });
  }
  </code></pre>
  
  <p>the first console.log prints the correct value for the path array, but after the callback for setstate is called, the second console.log prints an empty array. It's like this.setState were doing nothing</p>
  
  <p>For more details:
  I call pushDeck from a grandChild component, i give the function pushDeck as a prop to the component DeckGallery and this one gives the function to one of its children. here is the entire main component:</p>
  
  <pre><code>import React, {Component} from "react";
  import Page from "../components/page.jsx";
  import Radium from "radium";
  import {connect} from "react-redux";
  import {getUserInfo} from "../actions/user";
  import {successAlert} from "../actions/alerts";
  import {fetchUserDecks, deleteUserDeck} from "../actions/deck.js";
  import RaisedButton from 'material-ui/RaisedButton';
  import CreateUserDeckContainer from "../containers/createUserDeckContainer.jsx";
  import DeckGallery from "../components/deckGallery.jsx";
  import _ from "lodash";
  
  const style = {
      row1:{
          margin: "5px"
      },
      path:{
          color: "blue",
          cursor: "pointer"
      }
  }
  
  
  class Home extends Component{
  
      constructor(props){
          console.log("home constructor");
          super(props);
          this.state = {parentId:null, path:[]};
          this.fetchDecks = this.fetchDecks.bind(this);
          this.renderPath = this.renderPath.bind(this);
          this.goToIndex = this.goToIndex.bind(this);
          this.onDelete = this.onDelete.bind(this);
          this.pushDeck = this.pushDeck.bind(this);
      }
  
      componentWillMount(){
          console.log("will mount");
          this.props.getUserInfo();
      }
  
      fetchDecks(skip){
          console.log("fetch decks");
          this.props.fetchUserDecks(this.state.parentId, skip, this.state.path);
      }
  
      goToIndex(pathLastIndex){
          console.log("goto index", this.state.path);
          var limitToDrop = this.state.path.length - pathLastIndex;
          var newPath = _.dropRight(this.state.path, limitToDrop);
          this.setState({path: newPath});
      }
  
      pushDeck(id, name){
          var newDeck = [{id: id, name: name}];
          console.log("new path should be: ", Array.from(new Set(this.state.path.concat(newDeck))));
          this.setState({path: Array.from(new Set(this.state.path.concat(newDeck)))},
              ()=&gt;{
              console.log("setstate callback: ", this.state.path);
          });
      }
  
      componentWillUpdate(nextProps, nextState){
          console.log("nextstate: ",  nextState);
      }
  
      renderPath(){
          return (
              &lt;div&gt;
                  &lt;span onClick={()=&gt;this.goToIndex(0)} style={style.path}&gt;Root&lt;/span&gt;
                  {this.state.path.map((p, i)=&gt;{
                      &lt;span key={(i+1)} onClick={()=&gt;this.goToIndex(i+1)} style={style.path}&gt;{p.name}&lt;/span&gt;
                      })
                  }
              &lt;/div&gt;
          );
      }
  
      onDelete(deckId){
          console.log("on delete");
          this.props.deleteUserDeck(deckId, this.state.path, ()=&gt;{
              this.props.successAlert("Deck deleted succesfully !");
              this.forceUpdate();
          });
      }
  
      render(){
          console.log("path at render: ", this.state.path);
          return (
              &lt;Page name="my collection"&gt;
                  &lt;div className="container"&gt;
                      &lt;div style={style.row1} className="row"&gt;
                          &lt;div className="col-lg-9  col-sm-6"&gt;
                              &lt;h2&gt;Your decks&lt;/h2&gt;
                               Path: {this.renderPath()}
                          &lt;/div&gt;
                          &lt;div className="col-lg-3 col-sm-6"&gt;
                              &lt;CreateUserDeckContainer path={this.state.path}/&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
                      &lt;div className="row"&gt;
                          &lt;div className="col"&gt;
                              &lt;DeckGallery pushDeck={this.pushDeck} onDelete={this.onDelete} path={this.state.path} fetch={this.fetchDecks} decks={this.props.decks}/&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
              &lt;/Page&gt;
          );
      }
  }
  
  function mapStateToProps(state){
      return {decks: state.userDecks};
  }
  
  export default connect(mapStateToProps, {getUserInfo, fetchUserDecks, deleteUserDeck, successAlert})(Radium(Home));
  </code></pre>
  
  <p><strong>Update:</strong> I isolated the error to just this:</p>
  
  <pre><code>goToIndex(that){
          console.log("path at gotoindex: "+ JSON.stringify(that.state.path));
      }
  
      renderPath(){
          var that = this;
          console.log("path at renderpath: "+ JSON.stringify(that.state.path));   
          setTimeout(()=&gt;{
              that.goToIndex(that);
          }, 0);
          that.goToIndex(that);
      }
  </code></pre>
  
  <p>When i call render this is what gets printed in the console:</p>
  
  <pre><code>path at renderpath: [{"id":"59cec39e3724bc137d935ed5","name":"math"}]
  path at gotoindex: [{"id":"59cec39e3724bc137d935ed5","name":"math"}]
  path at gotoindex: []
  </code></pre>
  
  <p>the last line is printed when goToIndex is called from inside setTimeout, it should print the same thing than when called outside setTimeout.
  also, i putted a console.log in componentWillUpdate to see if the state was changing in the middle of both calls but is doesn't happen.</p>