You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Hooks复选框过滤课程数组异常问题求助

基于复选框标签过滤课程列表的问题修复

你当前的代码存在逻辑错误:勾选标签时会将对应课程叠加到现有列表中,而非根据所有选中标签重新过滤完整课程数组;取消勾选时直接从当前列表移除对应标签课程,导致状态依赖混乱,无法正确反映选中标签对应的全部课程。

错误原因分析

  1. 初始filterData设为全部课程,但勾选标签时执行setFilterData([...filterData, ...addedData]),是把新标签的课程追加进去,而非基于原始课程数组重新筛选
  2. 取消勾选时仅从当前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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 14:55:26