简体   繁体   中英

Why does the first iteration of my update to an array in state does not appear? It will only appear after the second iteration?

I have an array postArray defined in state on Main.js.

    this.state ={
        step: 1, 
        // welcome
        qNumber:1,
        accountNumber:'',
        amount:'',
        txNumber:1,
        postArray : []
    }

I also have a function on Main.js which inserts new array element into postArray:

insertTx =() => {
    // save transaction to array state
    // create copy of the array
    const copyPostArray = Object.assign([],this.state.postArray)
    // insert one element into the array
    copyPostArray.push({
        txNumber: this.state.txNumber+"-"+this.state.accountNumber,
        qNumber : this.state.qNumber,
        accountNumber : this.state.accountNumber,
        amount :   this.state.amount
    })
    // save the values back to array state
    this.setState({
        postArray:copyPostArray
    })
    console.log(this.state.postArray)
    console.log(this.state.txNumber)
    console.log(this.state.qNumber)
    console.log(this.state.accountNumber)
    console.log(this.state.amount)
}

On CashDeposit.js, postArray is being updated whenever I call InsertTx function below:

continue = e => {
    e.preventDefault();
    this.props.nextStep();
    //increment the txNumber
    // this.props.incTxNumber();
    this.props.insertTx();

Viewing the postArray on the console.log, it shows an empty array on first iteration. But for the second iteration, it will show the value for the first, on the third iteration will show value for the second and so on. Why does it not update current values?

setState does not happen right away. The state will always be the same values until the next render happens. If you update state, then in the same cycle reference state, you will get the old state. This would make it appear that you are one behind if you run something like:

this.setState(newValues) 
console.log(this.state) // old values

Make sure that when you are referencing state you don't rely on a setState from another function. This is where hooks and useEffect come in handy.

The issue you're seeing is caused by the fact that setState does not set the state immediately , you can think of it like an asynchronous operation. So when you try to log the state values, you are getting old values because the state hasn't changed yet.

In order to get access to the new state value, you can pass a callback to setState as a second parameter: this.setState(newState, updatedState => console.log(updatedState))

This is because setState() does not immediately update state . You will not see the updated state until the next time render() is called. Because of how React reconciles, this is pretty fast, because React won't try to build the DOM until all the setState() calls have been shaken out. But it also means that, while you can't see the new state immediately in the console, you can rest assured that you will see it eventually, before it appears in the browser.

It does, however, mean you need to be sure you've got your initial state condition handled in your code. If you don't set up your state in your constructor, you'll have at least one go-around where you'll need to render without undefined state throwing errors, for example.

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