问题描述
每次用户单击复选框时,都会调用
setLabels,从而产生与所选itemId匹配的项目列表。 (例如,如果选中了1.3,则for循环将贯穿exportEntries,获取与键1.3匹配的所有对象值)
然后我使用setState将filteredArray设置为返回的值。但是,下一次用户单击另一个复选框时,状态显然会重置。
我该如何维护所有先前选择的值并添加到状态中,而不是替换当前状态集?
setLabels = (e,itemId,itemLabel) => {
let fillerArray = [];
for (let item of this.state.exportEntries) {
if (itemId in item) {
fillerArray.push({ [itemLabel]: item[itemId] });
}
this.setState({
filteredArray: fillerArray
});
}
console.log(this.state.filteredArray);
e.preventDefault();
}
首先单击输出
0: {First: "One"}
1: {First: "Two"}
2: {First: "Three"}
3: {First: "Four"}
4: {First: "Five"}
第二次点击“输出”
0: {Second: "One"}
1: {Second: "Two"}
2: {Second: "Three"}
3: {Second: "Four"}
4: {Second: "Five"}
**编辑对象数组**
const singleValue = [...this.state.selectedValues];
for (let item of this.state.exportEntries) {
if (id in item) {
// This is pulling values from exportEntries that match the id
// of the 'label' selected. So 'First','Last',etc... all have
// an id that is passed to perform the check here.
singleValue.push({ [label]: item[id] });
}
}
for (var i = 0; i < singleValue.length; i++) {
merged.push({ ...this.state.selectedValues[i],...singleValue[i]})
}
// This is where I'm trying to merge the two arrays
// If I click First & Last this is returned:
// (10) [{…},{…},{…}]
// 0: {First: "First 1"}
// 1: {First: "First 2"}
// 2: {First: "First 3"}
// 3: {First: "First 4"}
// 4: {First: "First 5"}
// 5: {Last: "Last 1"}
// 6: {Last: "Last 2"}
// 7: {Last: "Last 3"}
// 8: {Last: "Last 4"}
// 9: {Last: "Last 5"}
// I want this:
// (5) [{…},{…}]
// 0: {First: "First 1",Last: "Last 1"}
// 1: {First: "First 2",Last: "Last 2"}
// 2: {First: "First 3",Last: "Last 3"}
// 3: {First: "First 4",Last: "Last 4"}
// 4: {First: "First 5",Last: "Last 5"}
解决方法
我仍然很难理解您的问题,但是基于我的最佳能力,我试图向您建议一些可行的方法。
我创建了一个POC来解决此问题。主要问题是您当前的状态是异步更新的,因此更新后立即访问它不会为您提供更新的状态。
在示例代码中,我添加了许多复选框,并且onChange
我正在更新状态以设置所有选中的复选框,并且在setSate
的回调中,我呼叫{ {1}}(我仍然不知道它的作用)。
这里重要的是在状态更新后进行处理。另外,看看您的代码,有两点特别突出:
- 您正在从冗余数组中调用
setLabels
,而您只想调用一次。 - 您一直在用新值
this.setState({ filteredArray: fillerArray });
更新fillterArray,可能是您希望let fillerArray = [];
保留旧选择。
看看这个POC代码:
let fillerArray = [...this.state.filteredArray];
,
据我所知,您希望正确地选中复选框并保留所有选中项的列表。您已经有filteredArray
。在setLabel
方法中,您必须添加当前项目(如果已选中),或者将其从列表中删除(如果尚未选中)。该事件应该为您提供此信息(e.checked
或其他内容)。
class SomeClass extends Component {
state = {
filteredArray: []
}
setLabels = (e,itemId,itemLabel) => {
const { filteredArray } = this.state
if(e.checked) {
this.setState({
filteredArray: [...filteredArray,{[itemLabel]: item[itemId]}]
})
} else {
this.setState({
filteredArray: filteredArray.filter(item => item[itemLabel]===undefined)
})
}
console.log(this.state.filteredArray);
e.preventDefault();
}
}
如果可以检查事件中的项目,则不应将其添加到数组中,因此将其追加。否则,它已经被添加并且将被过滤掉。
过滤器看起来有些奇怪。您拥有itemId
,我认为这是独一无二的。因此,我建议将itemId
显式添加到对象中,以具有更好的过滤条件。
该代码未经测试,但应以这种方式工作。
还要记住,console.log
可能不会给您正确的输出,因为setState
是不同步的。