React Hooks复选框过滤课程数组异常问题求助
基于复选框标签过滤课程列表的问题修复
你当前的代码存在逻辑错误:勾选标签时会将对应课程叠加到现有列表中,而非根据所有选中标签重新过滤完整课程数组;取消勾选时直接从当前列表移除对应标签课程,导致状态依赖混乱,无法正确反映选中标签对应的全部课程。
错误原因分析
- 初始
filterData设为全部课程,但勾选标签时执行setFilterData([...filterData, ...addedData]),是把新标签的课程追加进去,而非基于原始课程数组重新筛选 - 取消勾选时仅从当前
filterData中移除对应课程,没有基于原始courses数组重新计算,导致状态偏离真实筛选结果
解决方案
不需要单独维护filterData状态,直接基于checked数组和原始courses数组实时计算要显示的课程列表:
- 当
checked数组为空时,显示全部课程 - 当
checked数组有选中标签时,筛选出所有标签包含在checked中的课程 handleFilterItems只负责更新checked数组的状态,无需操作筛选后的课程数据
修改后的代码
import React, { useState } from "react"; const courses = [ { id: "1", course: "React Tutorial", tag: "react" }, { id: "2", course: "Object-oriented programming (OOP)", tag: "oop" }, { id: "3", course: "Java Programming", tag: "java" }, { id: "4", course: "JavaScript Course", tag: "javascript" }, { id: "5", course: "Spring Boot Tutorial", tag: "spring" }, { id: "6", course: "Python Bootcamp", tag: "python" }, { id: "7", course: "Spring Framework Course", tag: "spring" }, { id: "8", course: "React with Redux", tag: "react" }, { id: "9", course: "C#: Classes and OOP", tag: "oop" }, { id: "10", course: "Java Masterclass", tag: "java" }, { id: "11", course: "ES6 JavaScript Training", tag: "javascript" }, { id: "12", course: "Learn Python Programming", tag: "python" }, ]; const uniqueTags = [...new Set(courses.map((item) => item.tag))]; const App = () => { const [checked, setChecked] = useState<string[]>([]); const handleFilterItems = (event: React.ChangeEvent<HTMLInputElement>, tag: string) => { if (event.target.checked) { setChecked([...checked, tag]); } else { setChecked(checked.filter(item => item !== tag)); } }; // 实时计算要显示的课程 const displayCourses = checked.length === 0 ? courses : courses.filter(course => checked.includes(course.tag)); return ( <div style={{ textAlign: "center" }}> {uniqueTags.map((tag, index) => ( <label key={index} style={{ margin: "0 8px" }}> <input type="checkbox" checked={checked.includes(tag)} onChange={(event) => handleFilterItems(event, tag)} /> {tag} </label> ))} <hr /> <ul style={{ listStyle: "none", padding: 0 }}> {displayCourses.map((course) => ( <li key={course.id}> {course.id}-{course.course}-{course.tag} </li> ))} </ul> </div> ); }; export default App;
关键修改点
- 移除了
filterData状态,改用displayCourses变量实时计算筛选结果,彻底避免状态不同步问题 - 优化类型定义,将
checked类型从any改为string[],事件参数类型规范为React.ChangeEvent<HTMLInputElement> - 用
<ul>包裹课程列表项,符合HTML语义规范 - 添加少量内联样式,优化页面显示效果
内容的提问来源于stack exchange,提问作者MeAtWork
相关产品推荐
相关产品推荐

