我有数组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
}]
}))
}
}
答案 0 :(得分:1)
另一种方法是串联使用Array#filter
和Array#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()
条件以通过以下方式查找项目label
或uniqueId
根据您的需求。为了获得您的输出 问题,您必须通过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过滤切片,如果不存在则追加新的