简体   繁体   中英

setState not working in React JS

I am trying to give few dates to state.periods array. But it is not working. My code is as follows.

class SmallTable extends Component {
    constructor(props) {
        super(props);
        console.log(props.startDate)
        this.state = {
            turns: [],
            periods: []
        }
    }

componentDidMount() {
    //calculate years/ months and keep in one array
         const today = new Date();
         var periods1 = [];
         if (this.props.period=="year") { //if year calculate from last year last date
             const lastYearLastDate= new Date(new Date().getFullYear()-1, 11, 31)
             periods1.push(lastYearLastDate.getFullYear()+"-"+(lastYearLastDate.getMonth()+1)+"-"+lastYearLastDate.getDate());

             var lastYearFirstDate= new Date(lastYearLastDate.getFullYear()-1,0,1);

             //for the remaining periods
             for (var i=0;i<this.props.numberOfPeriods-1;i++) {
                 periods1.push(lastYearFirstDate.getFullYear()+"-"+(lastYearFirstDate.getMonth()+1)+"-"+lastYearFirstDate.getDate());
                 lastYearFirstDate = new Date(lastYearFirstDate.getFullYear()-1,0,1);
             }


         }


        else if (this.props.period=="month") {//if month calculate from last month last date
            var d=new Date(); // current date
            d.setDate(1); // going to 1st of the month
            d.setHours(-1); // going to last hour before this date even started.
            var lastMonthLastDate = d;
            periods1.push(lastMonthLastDate.getFullYear()+"-"+(lastMonthLastDate.getMonth()+1)+"-"+lastMonthLastDate.getDate());

            //go to last month  first date
            var lastMonthFirstDate = new Date(lastMonthLastDate.getFullYear(), lastMonthLastDate.getMonth(),1);

            //for the remaining periods
            for (var i=0;i<this.props.numberOfPeriods-1;i++) {
                periods1.push(lastMonthFirstDate.getFullYear()+"-"+(lastMonthFirstDate.getMonth()+1)+"-"+lastMonthFirstDate.getDate());

                lastMonthFirstDate=new Date(lastMonthFirstDate.getFullYear(), lastMonthFirstDate.getMonth()-1,1);
            }

        }

console.log(periods1); -->prints  ["2017-12-31", "2016-1-1", "2015-1-1", "2014-1-1"]
        this.setState((prevState)=>{
            return {
                periods: prevState.periods.push(periods1)
            }
        });
        console.log(this.state.periods) --> prints []

    }
render() {

        return ( <div></div>)
}

How to get values in periods1 to periods state. I am trying to insert periods1 array into state periods array. Those are strings. Pls suggest where the error might be.

You're setting this.state.periods to the result of a push operation. But push returns the new array length, not the array itself. Try this instead:

periods: [...prevState.periods, periods1]

You have a few issues.

For the code here:

return {
    periods: prevState.periods.push(periods1)
}

You never want to mutate state. Instead, you should create a new array object and then add the data, like so:

return {
    periods: prevState.periods.concat([periods1])
}

Secondly, your console.log is in the wrong place

console.log(this.state.periods) --> prints []

setState happens asynchronously and thus may not finish by the time your componentDidMount method returns. Instead, put that console.log inside your render function to see the new state.

push() doesn't return a value. You should use:

this.setState((prevState)=>{
    let old = prevState.periods.slice();
    old.push(periods1);
    return {
        periods: old
    }
});

If you expect this.state.periods to be an array of arrays ( [["2017-12-31", "2016-1-1", "2015-1-1", "2014-1-1"]] ) you can push your array following an immutable pattern using the spread operator :

this.setState((prevState) => ({
       periods: [...prevState.periods, periods1]
    }), () => { console.log(this.state.periods) } );

You can notice the function passed as second param of setState() is a callback to execute console.log() after the state update.

If you want to push periods1 values in this.state.periods you can do this :

this.setState((prevState) => ({
       periods: [...prevState.periods, ...periods1]
    }));

Try to make a copy of your original state , so that you can perform setState in an immutable fashion.

const periods = [...this.state.periods];
periods.push(periods1);
this.setState({periods: periods});

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