在React组件状态下修改数组中特定项目的最舒适/最常用的方法是什么?

时间:2018-06-04 13:57:15

标签: javascript reactjs ecmascript-6

我经常发现自己在React组件状态下操纵数组中的特定项目。例如:

state={
menus:[
  {
    id:1,
    title: 'something',
    'subtitle': 'another something',
    switchOn: false
  },
  {
    id:2,
    title: 'something else',
    'subtitle': 'another something else',
    switchOn: false
  },
 ]
}

此数组填充了具有各种属性的对象。其中一个属性当然是唯一的ID。这就是我根据其ID在项目上编辑“switchOn”属性的过程:

handleSwitchChange = (id) => {

  const newMenusArray = this.state.menus.map((menu) => {    
    if (menu.id === id) {
      return {
        ...menu,
        switchOn: !menu.switchOn
      };
    } else {
      return menu;
    };
  })
  this.setState(()=>{
    return{
      menus: newMenusArray
    }
  })   

}

正如您所看到的,很多麻烦,只是为了改变一个值。在AngularJS(1)中,我只会使用这样一个事实:对象通过引用传递,并且会直接改变它,而不会有任何ES6的喧嚣。

我有可能错过一些东西吗?有一种更直接的方法可以解决这个问题吗?任何一个例子将不胜感激。

2 个答案:

答案 0 :(得分:3)

一个好方法是让自己成为索引地图。就像您可能从数据库中了解它一样,它们不会迭代所有条目,而是使用索引。索引只是说ID A指向ID为A的对象

的一种方式

所以我正在做的是,建立一个索引地图,例如:减速机

const map = data.reduce((map, item) => {
    map[item.id] = item;
    return map;
}, {})

现在,只需说出

即可通过ID访问您的商品
map[myId]

如果要更改它,可以使用比对象分配或...语法

return {
    // copy all map if you want it to be immutable
    ...map
    // override your object
    [id]: {
        // copy it first
        ...map[id],
        // override what you want
        switchOn: !map[id].switchOn
    }
}

作为帮助库,我建议您使用Immutable.js,只需更改值作为参考

答案 1 :(得分:1)

我通常使用findIndex

handleSwitchChange = (id) => {
  var index = this.state.menu.findIndex((item) => {
    return item.id === id;
  });

  if (index === -1) {
    return;
  }

  let newMenu = this.state.menu.slice();
  newMenu[index].switchOn = !this.state.menu[index].switchOn;

  this.setState({
    menu: newMenu
  });
}