最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin1浏览0评论

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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论