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

React Hooks多复选框筛选课程数组功能失效求助

修复React复选框多标签筛选功能

问题根源

你的代码用单个字符串checked存储选中状态,仅能记录一个选项,完全不符合复选框多选的核心需求;同时筛选逻辑仅支持单标签匹配,无法实现多标签同时筛选。

修改方案

  1. 状态重构:将单个字符串状态改为数组,用来存储所有选中的标签
  2. 选中逻辑调整:实现标签的"选中/取消"切换,同时处理"All"与其他标签的互斥关系
  3. 多标签筛选逻辑:根据选中的标签数组,筛选出包含任意选中标签的课程
  4. 复选框状态同步:根据数组的包含关系判断每个复选框的选中状态

完整修改代码

import { useState, useMemo } 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 [checkedTags, setCheckedTags] = useState<string[]>([]);

  // 切换标签选中状态
  const handleToggleTag = (tag: string) => {
    setCheckedTags(prev => {
      if (tag === "all") {
        // 点击All时,切换选中状态:选中则清空其他标签,取消则恢复之前的选中项
        return prev.includes("all") ? [] : ["all"];
      } else {
        // 处理普通标签:已选中则移除,未选中则添加,同时取消All的选中状态
        return prev.includes(tag)
          ? prev.filter(t => t !== tag)
          : [...prev.filter(t => t !== "all"), tag];
      }
    });
  };

  // 用useMemo缓存筛选结果,避免不必要的重渲染
  const filteredCourses = useMemo(() => {
    // 选中All或无选中标签时,显示全部课程
    if (checkedTags.includes("all") || checkedTags.length === 0) {
      return courses;
    }
    // 筛选包含任意选中标签的课程
    return courses.filter(course => checkedTags.includes(course.tag));
  }, [checkedTags]);

  return (
    <div>
      <input
        type="checkbox"
        // All的选中状态:选中了all标签,或者没有选中任何标签(默认状态)
        checked={checkedTags.includes("all") || checkedTags.length === 0}
        onChange={() => handleToggleTag("all")}
      />{" "}
      All
      {uniqueTags.map((tag, index) => (
        <div key={index}>
          <input
            type="checkbox"
            // 普通标签的选中状态:已在选中数组中,且未选中All
            checked={checkedTags.includes(tag) && !checkedTags.includes("all")}
            onChange={() => handleToggleTag(tag)}
            // 可选:选中All时禁用其他标签,避免逻辑冲突
            disabled={checkedTags.includes("all")}
          />
          {tag}
        </div>
      ))}
      <ul>
        {filteredCourses.map((course) => (
          <li key={course.id}>
            {course.id}-{course.course}-{course.tag}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default App;

关键说明

  • 用useMemo缓存筛选结果,优化组件性能,避免每次渲染都重新遍历数组
  • 实现了"All"与其他标签的互斥逻辑:选中All时自动取消其他标签,选中其他标签时自动取消All
  • 添加了可选的disabled属性,当All选中时禁用其他标签,提升用户体验,避免逻辑冲突

内容的提问来源于stack exchange,提问作者MeAtWork

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:55:30