反应状态数组对象的更改而无需setState

时间:2018-08-15 19:34:53

标签: reactjs

我有一个数组,它是React组件的状态。该数组是一个清单。 var units1 = this.state.units;

当我更新unit1时,this.state.units会更改,而无需this.setState({unit:unit1})

我使用this.setState({ a: 2 });只是为了查看是否在没有this.setState({ units: units2 });的情况下更新了数组

this.state.units从道具获得其值,因此,如果状态改变,道具也会改变。

handleItemChange(e) {
  var units1 = this.state.units.slice();        
  var unit_name = parseInt(e.target.attributes.getNamedItem('data-unit_name').value);
 var new_unit;

  if (!e.target.checked && this.state.units && this.state.units.length > 0) {
  this.state.units.map((unit) => {
    if (unit_name == unit.codpacunidad) {
      if (unit.topics && unit.topics.length > 0) {
        unit.topics.map((topic) => {
          if (topic.codpacunidadtema == e.target.name) {
            new_unit = unit;
            var index = units1.indexOf(unit);
            //units1.splice(index, 1);

            units1 = update(units1, {$splice: [[index, 1]]})

            var topics1 = unit.topics.slice();
            index = topics1.indexOf(topic);
            //topics1.splice(index, 1);

            topics1 = update(topics1, {$splice: [[index, 1]]})

            new_unit.topics = topics1;
          }
        });
      }
    }
  });
} else {
  var found_unit = false;
  var name = parseInt(e.target.name);
  var order = parseInt(e.target.attributes.getNamedItem('data-order').value);
  var unit_order = parseInt(e.target.attributes.getNamedItem('data-unit_order').value);

  if (this.state.units && this.state.units.length > 0) {
    this.state.units.map((unit) => {
      if (unit.codpacunidad == unit_name) {
        found_unit = true;
        new_unit = unit;
        var index = units1.indexOf(unit);
        units1.splice(index, 1);

        var new_topic = {
          codpacunidadtema: name,
          orden: order
        };

        var topics2 = new_unit.topics;
        new_unit.topics = update(topics2, { $push: [new_topic]});
      }
    });
  }

  if (found_unit == false) {
    new_unit = {
      codpacunidad: unit_name,
      orden: unit_order,
      topics: [{codpacunidadtema: name, orden: order }]
    };
  }
}

// var units2 = update(units1, { $push: [new_unit]});
// this.setState({ units: units2.sort(function(a, b) {
//     return parseInt(a.orden) - parseInt(b.orden);
//   })
// });

this.setState({ a: 2 }); //just to test if the array gets updated without this.setStaet({ units: units2 })
}

有人知道为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

就像@Alexander van Oostenrijk所说的那样,对数组进行深层复制。


因为array是通过引用传递的,这意味着传递数组的内存地址不是传递array的值。

  var units1 = this.state.units.slice();

现在unit1拥有该数组的引用地址,对unit1或this.state.units.slice()所做的任何更改都会更改两者的值。基本上,它们都在使用地址,如果其中一个更改了address的值,则两者都会读取更改后的值。希望您能理解


要创建深层副本,您可以创建新对象,例如

var units1 = Object.assign([],this.state.units)

这将使用this.state.units的数据创建新对象 额外,我认为您不需要.slice()。