javascript - In React, what is the right way to update nested array state items - Stack Overflow

When using React (without Redux). Assuming I have ponent state that looks like this:{rows: [{items:[{va

When using React (without Redux). Assuming I have ponent 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, mon, 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?

When using React (without Redux). Assuming I have ponent 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, mon, 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?

Share Improve this question edited Feb 20, 2017 at 9:04 Lewis asked Feb 20, 2017 at 8:47 LewisLewis 5,8796 gold badges33 silver badges41 bronze badges 3
  • If you rephrase the question as to How would I do this in JavaScript without React? you'd have your answer. If you however ask Where would I do this? then you'd have a different question. – Henrik Andersson Commented Feb 20, 2017 at 8:51
  • 2 Related / possible duplicate: How to update an array at a particular index with React js – Felix Kling Commented Feb 20, 2017 at 8:59
  • @HenrikAndersson - I think the relevance of React is important because of what happens with state? I know how to do it with Javascript - what I'm interested in is the effect it has etc. I'll update my Question if you think it necessary ? – Lewis Commented Feb 20, 2017 at 8:59
Add a ment  | 

3 Answers 3

Reset to default 4
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-ponent.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' } } } } }
    )});

i am not sure which one is most popular or best, these things changes everyday. I use lodash.set for assigning

function updateItem(rowIndex, itemIndex, value) {
   const tmp = this.state.rows;
   _.set(tmp, `[${rowIndex}].item[${itemIndex}]`, value);
  this.setState({rows: tmp});
}

I use immutability-helper too.

for example:

this.state = {
    coupons: [
        {
            id: 1,
            title: 'coupon1'
        },
        {   
            id: 2,
            title: 'coupon2'
        },
        {
            id: 3,
            title: 'coupon3'
        }
    ]
}

And, you want to add a extend field like isChecked when user click the coupon.

handleCouponClick = (coupon, idx) => {
    const newState = {
        coupons: update(this.state.coupons, {
            [idx]: {
                isChecked: {$set: !this.state.coupons[idx].isChecked}
            }
        })
    };

    this.setState(newState);
}

So, the ponent will re-render and you can use the isChecked field to do something.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745455083a4628448.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信