React - how to add new element in array type state

2019-08-27 07:52发布

问题:

I have refereed this , this and this link to find solution but none of them work for me.

I have decleared state with array type and other state with null.

this.state = {  from: '', to: '',journeyDate: '',searchDetails: [] }

As user fill up search form with source city , destination city and journey date I set these state like below .

    let from = this.state.from;
    let to = this.state.to;
    let journeyDate = moment(this.state.journeyDate).format('YYYY-MM-DD'); 

final step to push these all variables into searchDetails array state. for that I have tried below options but none of them worked.

OPTION 1

this.setState({ searchDetails: [...this.state.searchDetails, from] });

OPTION 2

this.setState(prevState => ({
            searchDetails: [...prevState.searchDetails, from]
        }))

OPTION 3

let newState = this.state.searchDetails.slice();
        newState.push(from);

        this.setState({
            searchDetails: newState
        });
      console.log('final state is : ' + this.state.searchDetails);

every time console log remains empty.

any advice ?

回答1:

Try :

this.setState({
    searchDetails: newState // use any of your 3 methods to set state
},() => {
     console.log('final state is : ' + this.state.searchDetails);
});

setState() does not always immediately update the component. It may batch or defer the update until later.

This makes reading this.state right after calling setState() a potential pitfall.

Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.

For More Detail, Please read : https://reactjs.org/docs/react-component.html#setstate



回答2:

Actually setState is an asynchronous method. That means right after writing setState, you cannot expect the state to be changed immediately. So console.log right after setState may show you last state instead of new state. If you want to log the updated state then use the callback of setState which is called when state is updated like this

this.setState({ searchDetails: [...this.state.searchDetails, from] }, () => { 
    console.log(this.state.searchDetails)
});