ReactJS:用新值替换数组中的对象将替换整个数组

时间:2019-09-16 04:56:05

标签: javascript arrays reactjs

我有数组selectedItems,当我尝试更新现有对象时:

i.e. [{lable: "one", uniqueId: 1}, {lable: "two", uniqueId: 1}] 

收件人:

i.e. [{lable: "one", uniqueId: 1}, {lable: "two", uniqueId: 3}]

它将整个数组替换为:

 [ { lable: "two", uniqueId: 3 }]

如何避免这种情况?

handleChange = (label, uniqueId) => {
  const { selectedItems } = this.state
  const findExistingItem = selectedItems.find((item) => {
    return item.uniqueId === uniqueId;
  })

  if(findExistingItem) {
    selectedItems.splice(findExistingItem);
    this.setState(state => ({
      selectedItems: [...state.selectedItems, {
        label, uniqueId
      }]
    }))
  } else {
    this.setState(state => ({
      selectedItems: [...state.selectedItems, {
        label, uniqueId
      }]
    }))
  }
}

5 个答案:

答案 0 :(得分:1)

另一种方法是串联使用Array#filterArray#concat函数,其中;

    uniqueId上不匹配的
  • 个项目被过滤。这将替代您当前解决方案的find()逻辑,
  • 调用concat()方法以将新的“替换项”附加到过滤后的数组的末尾

在可以这样实现的代码中:

handleChange = (label, uniqueId) => {
  const {
    selectedItems
  } = this.state

  this.setState({
    selectedItems : selectedItems
      /* Filter any existing item matching on uniqueId */
      .filter(item => (item.uniqueId !== uniqueId))
      /* Append replacement { label, uniqueId } to state array */
      .concat([ { label, uniqueId } ])
  });
}

答案 1 :(得分:0)

Array.find()在数组中找到元素并返回其引用。

您可以修改返回的对象,然后更新状态。

  

此外,您可以更改find()条件以通过以下方式查找项目   labeluniqueId根据您的需求。为了获得您的输出   问题,您必须通过label而不是uniqueId查找。

handleChange = (label, uniqueId) => {
  const { selectedItems } = this.state;

  const findExistingItem = selectedItems.find((item) => {
    // To find by 'label', replace 'uniqueId' below with 'label'.
    return item.uniqueId === uniqueId;
  })

  if(findExistingItem) {
    // You are not passing in 'newUniqueId', so only 'label' is updated.
    findExistingItem.label = label;
    findExistingItem.uniqueId = uniqueId;
  } 

  this.setState(state => ({
    selectedItems: selectedItems
  }));
}

实时示例:

function handleChange(label, uniqueId) {

  const selectedItems = [{label: "one",uniqueId: 1}, {label: "two", uniqueId: 1 }];

  const findExistingItem = selectedItems.find(item => { 
     // Finding by 'label', change to 'uniqueId' if that is what is needed.
     return item.label === label;
  });

  if(findExistingItem) {
    findExistingItem.label = label;
    findExistingItem.uniqueId = uniqueId;
  } 
 
  console.log(JSON.stringify(selectedItems));
}

handleChange("two", 3);

答案 2 :(得分:-1)

如果省略.splice的第二个参数(要删除的元素数),则会从以下位置的索引中删除所有元素:

  const arr = [1, 2, 3];
  arr.splice(0);
  console.log(arr);

您可能只想拼接1,并且可能想从元素索引开始,而不是它的值。

答案 3 :(得分:-1)

我认为这个问题具有误导性

我认为OP要做的是找到传递给函数的标签并更改匹配数组条目的uniqueId-给出的结果为[{lable: "two", uniqueId: 3}]意味着将调用handleChange

handleChange('two', 3);

鉴于逻辑更像以下内容

handleChange = (label, uniqueId) => {
    this.setState(state => ({
        selectedItems: state.selectedItems.map(item => Object.assign(item, item.lable === label ? {uniqueId} : {}))
    });
}

举例说明:

const handleChange = (label, uniqueId) => {
    const selectedItems = [{lable: "one", uniqueId: 1}, {lable: "two", uniqueId: 1}];
    return selectedItems.map(item => Object.assign(item, item.lable === label ? {uniqueId} : {}))
};

console.log(handleChange('two', 3));


或者“借用”一些更好的代码,并对其进行修复

handleChange = (lable, uniqueId) => {
    const { selectedItems } = this.state
    const selectedItem = selectedItems.filter(item => item.lable !== lable)
    this.setState({  selectedItems:  [...selectedItem, { lable, uniqueId }] })
}

演示其工作原理并产生预期结果:

const handleChange = (lable, uniqueId) => {
    const selectedItems = [{lable: "one", uniqueId: 1}, {lable: "two", uniqueId: 1}];
    const selectedItem = selectedItems.filter(item => item.lable !== lable)
    return({  selectedItems:  [...selectedItem, { lable, uniqueId }] })
};

console.log(handleChange('two', 3));

答案 4 :(得分:-1)

您可以过滤和设置状态

handleChange = (label, uniqueId) => {
  const { selectedItems } = this.state
  // filter data if exists other wise return present array
  const selectedItem = selectedItems.filter(item => item.uniqueId !== uniqueId)

  this.setState({  selectedItems:  [...selectedItem, { label, uniqueId }] })
}

根据uniqueId过滤切片,如果不存在则追加新的

相关问题