Dave_888
Dave_888

Reputation: 433

setState not working for updating an array in React

I try to update a state in a location object. somehow the setState isn't working for me.

The console.log does return the newName correctly.

I don't see directly where my fault is. Can someone tell me where my error is?

state = {
    locations: [
       {name:"name1", address:"address1", locationSelected:false},
       {name:"name2", address:"address2", locationSelected:false}
    ]
}

selectLocationHandler = (id) => {
    let theLocations = [...this.state.locations];
    theLocations[id] = {...theLocations[id], name:"newName!!!!"};
    console.log(theLocations[id].name + "testtest");

    this.setState({theLocations}, () => {
        console.log(this.state.locations[id].name + " it worksss");
    });
}

Upvotes: 16

Views: 34690

Answers (3)

Gonki
Gonki

Reputation: 736

Reset the array to empty then set the state to the new value:

 this.setState({ locations: [] }, () => this.setState({ locations: theLocations }))

Upvotes: 0

Kevin Smith
Kevin Smith

Reputation: 277

The main problem with this code is that your are altering a state object directly. You should treat all state objects as if they are immutable. In your code, you do not actually need the setState call because the state would already be updated. When you define theLocations, you are cloning the array, but not the objects in that array.

To clone an array of objects, use this:

const theLocations = this.state.locations.map(l => Object.assign({}, l));

Once you have your cloned array of objects, just set the name like this:

theLocations[id].name = "newName!!!!";

Another error here is that you are saving theLocations as a new property in your state object. You need to set locations as the key in your setState function:

this.setState({locations: theLocations}, () => {});

Complete code:

selectLocationHandler = (id) => {
    const theLocations = this.state.locations.map(l => Object.assign({}, l));
    theLocations[id].name = "newName!!!!";
    this.setState({locations: theLocations}, () => {
      console.log(this.state.locations[id].name + " it worksss");
    });
}

Upvotes: 15

Alexandr Nituleac
Alexandr Nituleac

Reputation: 31

In setState you should specify name of property in the state which you want to update. In your case {theLocations} means that you have the next object {theLocations: theLocations}. You need to change it to: this.setState({locations: theLocations}, () => { console.log(this.state.locations[id].name + " it worksss"); });

Upvotes: 3

Related Questions