在React中,更新嵌套数组状态项的正确方法是什么

时间:2017-02-20 08:47:55

标签: javascript reactjs ecmascript-6

使用React(不使用Redux)时。假设我的组件状态如下所示:

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

还假设行和项的长度为0> 0。 Ñ

更新任何项目的价值的最佳(最有效,最普遍,同意,流行等)方式是什么,即

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

我意识到我能做到:

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

this.setState({
  rows: updatedRows
})

这一般被接受了吗?替换几乎整个状态对象来改变单个值是不是很低效?

3 个答案:

答案 0 :(得分:2)

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

由于item[1]是一个对象,因此更改其value会改变您的状态,因为它引用同一个对象。

您永远不应该直接改变状态,因为当您直接修改状态时,react不会触发相关的生命周期事件。来自文档(https://facebook.github.io/react/docs/react-component.html):

  

不要直接改变this.state,因为之后调用setState()可能   替换你所做的突变。把它当作状态对待   不可变的。

我喜欢使用immutability-helper库来复制状态中的对象。例如,要将value this.state.rows[0].item[1]更改为z

this.setState({rows: update(this.state.rows, 
        { 0: { item: { 1: { value: { $set: 'z' } } } } }
    )});

答案 1 :(得分:0)

我不确定哪一个最受欢迎或最好,这些东西每天都在变化。我使用lodash.set进行分配

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

答案 2 :(得分:0)

我也使用immutability-helper

例如:

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

并且,当用户点击isChecked时,您希望添加coupon等扩展字段。

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

    this.setState(newState);
}

因此,该组件将re-render,您可以使用isChecked字段执行某些操作。