在react with hook中用唯一的值更新对象中的数组



我有两个选择列表,我可以从中选择值

list one= "A", "B">

列表两="C"D"E","F"

我有一个反应状态const [filterTags, setFilterTags] = useState({ one: [], two: [] });

我可以每次从updateValue(val)中的任意列表传递一个val我需要以这样一种方式更新过滤器标签,如果它的val来自AB列表one,它应该像这样更新状态{one:["A"]: two:[]}

const updateValue = (val) => {
if (val === 'A' || val === 'B') {
setFilterTags({ one: val });
} else {
setFilterTags({ ...filterTags, two: val });
}
};

如果我逐个传递A C C D B A E C,它应该用唯一的值更新数组,输出应该是

{one:["A"]: two:[]} //passing A
{one:["A"]: two:["C"]} //passing C
{one:["A"]: two:["C"]} // same since C is already there in two on passing C
{one:["A"]: two:["C","D"]} //passing D
{one:["A","B"]: two:["C","D"]}  //passing B
{one:["A","B"]: two:["C","D"]} //same since A is already present in one on //passing A
{one:["A","B"]: two:["C","D","E"]} //passing E
{one:["A","B"]: two:["C","D","E"]}// final output on passing C

应该用唯一的值更新相应的元素现在上面的代码只能更新一个值

您应该确保您只添加了不存在的元素,您可以使用数组上的includes函数来检查这一点,并且您还希望确保您保留了所有以前的内容。

一个可能的解决方案是这样做:

const updateValue = (val) => {
if (val === 'A' || val === 'B') {
if(!filterTags.one.includes(val)) {
setFilterTags((prev) => ({ one: [...prev.one, val], two: prev.two }));
}
} else {
if(!filterTags.two.includes(val)) {
setFilterTags((prev) => ({ one: prev.one, two: [...prev.two, val] }));
}
}
};

下面的注释代码可以帮助您:

const updateValue = (val) => {
//creating a temporary copy of filterTags
const tempFilterTags = {...filterTags}
//checking if val is A or B and if finterTag.one does not contain the value
if ((val === 'A' || val === 'B') && filterTags.one.find(el=> el == val) === null) {
//if success, push the value for field one and update filterTag
tempFilterTags.one.push(val)
setFilterTags(tempFilterTags)
} 
//checking if val is C, D, E of F and if finterTag.two does not contain the value
if ((val === 'C' || val === 'D' || val === 'E' || val === 'F') && filterTags.two.find(el=> el == val) === null) {
//if success, push the value for field two and update filterTag
tempFilterTags.two.push(val)
setFilterTags(tempFilterTags)
} 
};

在设置状态时,使用功能更新选项获取以前的值(prev),并使用扩展使用以前和更新的值创建新状态。使用Set来维护唯一的值。

const updateValue = (val) => {
if (val === 'A' || val === 'B') {
setFilterTags(prev => ({ ...prev, one: [...new Set([...prev.one, val])] }));
} else {
setFilterTags(prev => ({ ...prev, two: [...new Set([...prev.two, val])] }));
}
};

为什么这里有太多的代码重复,因为设置状态的逻辑是相同的,只是键改变了,所以你可以重构它:

const updateValue = (val) => {
const key = val === 'A' || val === 'B' ? 'one' : 'two';

setFilterTags(prev => ({ ...prev, [key]: [...new Set([...prev[key], val])] }));
};

你也可以像Houssam建议的那样使用Array.includes来避免更新状态:

const updateValue = (val) => {
const key = val === 'A' || val === 'B' ? 'one' : 'two';
setFilterTags(prev => {
const key = val === 'A' || val === 'B' ? 'one' : 'two';

return prev[key].includes(val)
? prev
: { ...prev, [key]: [...prev[key], val] };
});
};

最新更新