ReactJS有复选框过滤的问题



我很难排除复选框过滤问题,因为我是ReactJS的初学者。我使用的代码是基于我从互联网上找到的参考,我根据我的要求改变了它。由于我缺乏知识,有一个问题我需要帮助:

1)过滤过程有一些问题,我有两个不同的过滤过程(filterList &filterList2)。当我尝试在UseEffect中整合它们时,它的工作效果不佳,因为它似乎覆盖了第一个过滤过程(filterList)。只有当我删除第二个过滤过程(filterList2)时,filterList才会工作。

我希望实现的结果是,我应该能够通过选中filterList和filterList2复选框来显示过滤结果,其中过滤过程将涉及使用searchList作为示例数据

创建数组 的代码
// First List: Learning Direction
const filterList = [
{
learningDirection: "Today"
},
{
learningDirection: "Tomorrow"
},
{
learningDirection: "Leadership and Development"
}
];
// Second List: Target Audience
const filterList2 = [
{
targetAudience: "Ancillary Staff"
},
{
targetAudience: "Clinical Staff"
},
{
targetAudience: "Educators"
},
{
targetAudience: "Management Staff"
},
{
targetAudience: "Researchers"
},

];
// Data
const searchLists = [
{
id: 1,
name: "Course 1",
learningDirection: "Today",
targetAudience: "Ancillary Staff",
},
{
id: 2,
name: "Course 2",
learningDirection: "Tomorrow",
targetAudience: "Researchers",
},
{
id: 3,
name: "Course 3",
learningDirection: "Today",
targetAudience: "Management Staff",
},
{
id: 4,
name: "Course 4",
learningDirection: "Leadership and Development",
targetAudience: "Educators",
},
{
id: 5,
name: "Course 5",
learningDirection: "Leadership and Development",
targetAudience: "Clinical Staff",
}
];

创建过滤过程代码

const [learningDirection, setlearningDirection] = useState([]);
const [targetAudience, settargetAudience] = useState([]);
const [filteredlist, setFilteredlist] = useState([]);

const handleChange1 = (e) => {
if (e.target.checked) {
setlearningDirection([...learningDirection, e.target.value]);
} else {
setlearningDirection(learningDirection.filter((id) => id !== e.target.value));
}
if (e.target.checked) {
settargetAudience([...targetAudience, e.target.value]);
} else {
settargetAudience(targetAudience.filter((id) => id !== e.target.value));
} 
};

useEffect(() => {
if (learningDirection.length === 0) {
setFilteredlist(searchLists);
} else {
setFilteredlist(
searchLists.filter((filterList) =>
learningDirection.some((category) => [filterList.learningDirection].flat().includes(category))
)
);
}

if (targetAudience.length === 0) {
setFilteredlist(searchLists);
} else {
setFilteredlist(
searchLists.filter((filterList2) =>
targetAudience.some((category) => [filterList2.targetAudience].flat().includes(category))
)
);
}
}, [learningDirection,targetAudience]);
显示复选框 的代码
<div className="searchContainer">
<form>

<b style={{ textAlign: "center", color:"white" }}> 
Learning Direction 
</b>
<br/>

<div style={{ textAlign: "left",color:"white" }}>
<hr/>
<FormControl>
<FormGroup>
{filterList.map((filterList) => (
<FormControlLabel
type="checkbox"
control={<Checkbox onChange={handleChange1} />}
label={filterList.learningDirection}
value={filterList.learningDirection}
/>
))}
</FormGroup>
</FormControl>

<hr/>
<FormControl>
<FormGroup>
{filterList2.map((filterList2) => (
<FormControlLabel
type="checkbox"
control={<Checkbox onChange={handleChange1} />}
label={filterList2.targetAudience}
value={filterList2.targetAudience}
/>
))}
</FormGroup>
</FormControl>


</div>
</form>
</div>
显示filteredlist数据的代码
<Fragment>

{filteredlist.map((item, index) => (

<Card style={{ background: "lightgreen", marginBottom: "5px" }}>
<Typography gutterBottom variant="h6" noWrap>
Course Name: {item.name}
</Typography>
<Typography gutterBottom variant="h6" noWrap>
Course Type: {item.learningDirection}
</Typography>
<Typography gutterBottom variant="h6" noWrap>
Audience: {item.targetAudience}
</Typography>
</Card>
))}

</Fragment>

所以我在让代码框工作时遇到了一点麻烦。不过我还是发现了这个问题。这里有两个大问题。原:

const handleChange1 = (e) => {
if (e.target.checked) {
setlearningDirection([...learningDirection, e.target.value]);
} else {
setlearningDirection(
learningDirection.filter((id) => id !== e.target.value)
);
}
if (e.target.checked) {
settargetAudience([...targetAudience, e.target.value]);
} else {
settargetAudience(targetAudience.filter((id) => id !== e.target.value));
}
};

你不应该把这些都放在一个函数中。现在的工作方式是,每个被检查的输入都被分配给两个过滤器(由于useEffect,只破坏第一个过滤器)。一个好的经验法则是将每个setState绑定到一个函数(有时这是不可避免的,但这就是我在这里要做的)。我的意思是。解决方案:

const handleLearningDirectionChange = (e) => {
if (e.target.checked) {
setlearningDirection([...learningDirection, e.target.value]);
} else {
setlearningDirection(
learningDirection.filter((id) => id !== e.target.value)
);
}
};
const handleTargetAudienceChange = (e) => {
if (e.target.checked) {
settargetAudience([...targetAudience, e.target.value]);
} else {
settargetAudience(targetAudience.filter((id) => id !== e.target.value));
}
};
// TODO: Change the onChange inside the forms

在useEffect中还有第二个问题。原:

useEffect(() => {
if (learningDirection.length === 0) {
setFilteredlist(searchLists);
} else {
setFilteredlist(
searchLists.filter((filterList) =>
learningDirection.some((category) =>
[filterList.learningDirection].flat().includes(category)
)
)
);
}
if (targetAudience.length === 0) {
setFilteredlist(searchLists);
} else {
setFilteredlist(
searchLists.filter((filterList2) =>
targetAudience.some((category) =>
[filterList2.targetAudience].flat().includes(category)
)
)
);
}
}, [learningDirection, targetAudience]);

第二个setFilteredlist()将覆盖第一个。所以learningDirection过滤器没有做任何事情。这个修复有点混乱,但它确实有效。解决方案:(编辑:用searchLists初始化set,并更改过滤器来查找删除。也删除了不必要的if语句)

useEffect(() => {
const set = new Set([...searchLists]);
learningDirection.forEach((direction) => {
searchLists.forEach((item) => {
// Change this to "===" if you want the opposite result
if (item.learningDirection !== direction) {
set.delete(item);
}
});
});
targetAudience.forEach((audience) => {
searchLists.forEach((item) => {
// Change this to "===" if you want the opposite result
if (item.targetAudience !== audience) {
set.delete(item);
}
});
});
setFilteredlist([...set]);
}, [learningDirection, targetAudience]);

我们使用Set来避免重复的值,循环检查的值,然后循环searchList来获得结果。这首先发生,然后我们将结果赋值给状态(使用…

总的来说,我想要完全重构这个组件。这里的解决方案应该能让你振作起来,继续前进,但我觉得在你处理事情的方式上似乎有很多不必要的复杂性。我必须花更多的时间去了解到底发生了什么,才能真正确定这一点,并提供一个更好的替代方案。

Edit2:提供两个备选

我猜这就是你想要的过滤器:

// Have all the results
const set = new Set([...searchLists]);
// Remove unselected check boxes (if any are selected)
if (learningDirection.length) {
searchLists.forEach((item) => {
if (!learningDirection.includes(item.learningDirection)) {
set.delete(item);
}
});
}
// Remove more unselected check boxes (if any are selected)
if (targetAudience.length) {
searchLists.forEach((item) => {
if (!targetAudience.includes(item.targetAudience)) {
set.delete(item);
}
});
}
setFilteredlist([...set]);

或者这个?

// Start empty if there's any selected checkboxes
const set =
learningDirection.length > 0 || targetAudience.length > 0
? new Set()
: new Set([...searchLists]);
// Add to empty set if any checkboxes are selected
if (learningDirection.length) {
searchLists.forEach((item) => {
if (learningDirection.includes(item.learningDirection)) {
set.add(item);
}
});
}
// Add more if any checkboxes are selected
if (targetAudience.length) {
searchLists.forEach((item) => {
if (targetAudience.includes(item.targetAudience)) {
set.add(item);
}
});
}
setFilteredlist([...set]);

相关内容

  • 没有找到相关文章

最新更新