Skip to content Skip to sidebar Skip to footer

React: Update Nested State?

I'm using react native. Suppose I've this state: { persons: [{ name: 'Person', id: 0, value: '', percent: 50, messed: false }, { name: 'Person', id: 1, value: '',

Solution 1:

You shouldn't be updating the state directly as react mentions several time in their docs. An option you can use is the spread oeprator (or Object.assign):

let newPersonsList = [...this.state.persons];
newPersonsList[2] = {...newPersonsList[2], percent:0};
this.setState({persons:newPersonsList});

Note spread operators only go 1 level deep in copying arrays, i believe, so you are taking the same references for all the persons objets and placing them in a new array. Then you are creating a new object with an updated percent property and assigning it to replace an old reference. Performance wise this should be quick, since no extensive deep copy occurs.

Alternately if you find yourself having a lot of nested objects needing to be updated, i would suggest you take a look at the following library: immutability-helper. Its specifically designed for such cases.

Solution 2:

You would have to update the whole state, pretty similar to what you're doing. However, instead of using this.forceUpdate(), I'd recommend calling this.setState({ persons: this.state.persons }).

What you may want to do is consider flatting out your persons into the state. You could do something like create a unique key for each based on their index. So, index of something like this:

const persons = getPersonsData();
this.setState({ persons });

Instead do something like this:

const persons = getPersonsData();
this.setState(persons.reduce((result, person, index) =>Object.assign(result, { [`person${index}`]: person }));

The persons.reduce bit will take your array and create an object like this:

{
    person0: {},
    person1: {},
    person2: {}
}

Then, each person will be flat in the state so you can just update it more directly. Not a huge difference, but depending on your use-case, could be worthwhile.

Solution 3:

I would just use setState. Let React worry about the performance optimizations

this.setState(object.assign({}, this.state, 
      this.state.persons.map(p => {
        if (p.id === id) p.percent = 0;
      }
   )))

Solution 4:

another way to change the state, but flatten state by person id maybe the better option.

state= {
       persons: [{
          name:"Person",
          id:0,
          value:"",
          percent:50,
          messed:false
        },
        {
          name:"Person",
          id:1,
          value:"",
          percent:50,
          messed:false
        }]
 }

 this.setState(({persons})=> {
   persons.filter(i=>i.id===1).map(i=>i.percent=0)
 })}

Post a Comment for "React: Update Nested State?"