问题 以不可变的方式更新数组中的一个对象


在React的this.state中我有一个叫做的属性 formErrors 包含以下动态对象数组。

[
  {fieldName: 'title', valid: false}, 
  {fieldName: 'description', valid: true},
  {fieldName: 'cityId', valid: false},
  {fieldName: 'hostDescription', valid: false},
]

假设我需要更新具有fieldName的state对象 cityId 到有效值 true

解决这个问题的最简单或最常用的方法是什么?

我可以使用任何库 不变性辅助不可改变的js 等或ES6。我试过用谷歌搜索超过4个小时,仍然无法绕过它。非常感谢一些帮助。


1389
2018-05-04 20:44


起源

您是否尝试迭代数组,如果 fieldName === 'cityId' 然后设定 valid 至 true?这看起来非常简单......我错过了什么?如果您发布了一些您尝试过的东西,它可能会有所帮助。 - alexanderbird
我也和@alexanderbird一样思考,所以你有特定的性能要求吗? - Junbang Huang
我的问题是关于处理 不可变数据。 - Fellow Stranger


答案:


您可以使用 map 迭代数据并检查fieldName,如果fieldName是cityId,那么你需要更改值和 返回一个新对象 否则只是 return 一样 object

写这样:

var data = [
    {fieldName: 'title', valid: false}, 
    {fieldName: 'description', valid: true},
    {fieldName: 'cityId', valid: false},
    {fieldName: 'hostDescription', valid: false},
]

var newData = data.map(el => {
                  if(el.fieldName == 'cityId')
                     return Object.assign({}, el, {valid:true})
                  return el
              });

this.setState({ data: newData }); 

13
2018-05-04 20:57





怎么样 不变性辅助?效果很好。你正在寻找 $merge 命令我想。

@FellowStranger:我的redux状态有一个(也是唯一一个)部分是一个对象数组。我使用reducer中的索引来更新正确的条目:

case EMIT_DATA_TYPE_SELECT_CHANGE:
  return state.map( (sigmap, index) => {
    if ( index !== action.payload.index ) {
      return sigmap;
    } else {
      return update(sigmap, {$merge: {
        data_type: action.payload.value
      }})
    }
})

坦率地说,这有点油腻,我打算改变我的状态对象的那部分,但它确实有用......听起来你并没有使用redux,但战术应该是相似的。


1
2018-05-04 20:56



问题是我已经尝试了但是无法理解他们的语法如何替换对象数组中的值:/ - Fellow Stranger
只需按照此处的示例: github.com/kolodny/immutability-helper#nested-collections。你想要更新 valid 索引2处对象的参数,所以类似于 update(formErrors, {2: {valid: {$set: true}}}) - Hamms
要么 update(formErrors, {2: {$merge: {valid: true}}}) - Hamms
@FellowStranger绝对是不可变的帮助者的更新功能。非常非常有用。学习语法确实需要一段时间...... - Omortis


我强烈建议您不要将值存储在数组中,而是可以轻松指定要更新的元素。在下面的示例中,键是fieldName,但它可以是任何唯一标识符:

var fields = {
    title: {
        valid: false
    },
    description: {
        valid: true
    }
}

那么你可以使用immutability-helper's update 功能:

var newFields = update(fields, {title: {valid: {$set: true}}})

1
2018-05-04 21:10