Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setState not working for updating an array in React

Tags:

reactjs

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");
    });
}
like image 253
Dave_888 Avatar asked Apr 25 '18 20:04

Dave_888


People also ask

Why is setState not updating immediately?

setState , and React. useState create queues for React core to update the state object of a React component. So the process to update React state is asynchronous for performance reasons. That's why changes don't feel immediate.

How do you update setState in React?

Before updating the value of the state, we need to build an initial state setup. Once we are done with it, we use the setState() method to change the state object. It ensures that the component has been updated and calls for re-rendering of the component.


1 Answers

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");
    });
}
like image 63
Kevin Smith Avatar answered Nov 11 '22 14:11

Kevin Smith