admin管理员组

文章数量:1425686

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.

本文标签: javascriptIn Reactwhat is the right way to update nested array state itemsStack Overflow