Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In React, what is the right way to update nested array state items

Tags:

When using React (without Redux). Assuming I have component state that looks like this:

{
    rows: [
    {
      items:[
         {
           value:'a',
           errors: false
         },
         {
           value:'b',
           errors: false
         },
         {
           value:'c',
           errors: false
         }
     ]
  }

Also assuming that the rows and items can be of length 0 > n.

What is the best (most efficient, common, agreed, popular etc) way to update the value of any of the items, i.e.

this.state.rows[0].item[1]

I realise that I can do:

let updatedRows = this.state.rows
updatedRows[0].item[1].value = 'new value'

this.setState({
  rows: updatedRows
})

Is this generally accepted what of doing this? Isn't it inefficient to replace pretty much the whole state object to change a single value?

like image 791
Lewis Avatar asked Feb 20 '17 08:02

Lewis


1 Answers

let updatedRows = this.state.rows
updatedRows[0].item[1].value = 'new value'

Because item[1] is an object, changing its value mutates your state since it refers to the same object.

You should never mutate the state directly because when you modify the state directly, react won't fire the relevant lifecycle events. From the docs (https://facebook.github.io/react/docs/react-component.html):

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

I like to use the immutability-helper library to make copies of objects in the state. For example to change the value of this.state.rows[0].item[1] to z:

this.setState({rows: update(this.state.rows, 
        { 0: { item: { 1: { value: { $set: 'z' } } } } }
    )});
like image 148
FuzzyTree Avatar answered Sep 23 '22 10:09

FuzzyTree