我有两个选择列表,我可以从中选择值
list one= "A", "B">
列表两="C"D"E","F"
我有一个反应状态const [filterTags, setFilterTags] = useState({ one: [], two: [] });
我可以每次从updateValue(val)
中的任意列表传递一个val我需要以这样一种方式更新过滤器标签,如果它的val
来自A
或B
列表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] };
});
};