React Hooks实现单选按钮过滤课程数组:选中状态不生效求助
React Hooks单选按钮过滤课程数组时选中状态异常修复
问题演示

问题描述
使用React Hooks通过单选按钮基于唯一标签(tag)过滤课程对象数组,过滤功能已实现,但单选按钮的选中状态无法正常显示,需要完善<input type="radio" 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: any) => item.tag))]; const App = () => { const [filterData, setFilterData] = useState(courses); const handleFilterItems = (tag: any) => { setFilterData(courses); const filteredItems = courses?.filter((item: any) => item.tag === tag); setFilterData(filteredItems); }; return ( <> <input type="radio" onChange={() => setFilterData(courses)} /> All {uniqueTags.map((tag, index) => ( <div key={index}> <input type="radio" key={index} // checked={tag} value={tag} onChange={() => handleFilterItems(tag)} /> {tag} </div> ))} {filterData.map((course: any) => ( <li key={course.id}> {course.id}-{course.course}-{course.tag} </li> ))} </> ); }; export default App;
修复方案
问题核心是缺少跟踪当前选中标签的状态,仅靠filterData无法直接判断选中项,需要新增状态变量记录当前激活的标签,同时规范单选按钮的组属性:
修复后的完整代码
import React, { 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 = () => { // 记录当前选中的标签,初始为'all'对应全部选项 const [selectedTag, setSelectedTag] = useState<string>('all'); // 缓存过滤结果,仅在选中标签变化时重新计算 const filterData = useMemo(() => { if (selectedTag === 'all') { return courses; } return courses.filter(item => item.tag === selectedTag); }, [selectedTag]); return ( <> <div> <input type="radio" name="courseFilter" value="all" checked={selectedTag === 'all'} onChange={() => setSelectedTag('all')} /> All </div> {uniqueTags.map((tag) => ( <div key={tag}> <input type="radio" name="courseFilter" value={tag} checked={selectedTag === tag} onChange={() => setSelectedTag(tag)} /> {tag} </div> ))} <ul> {filterData.map((course) => ( <li key={course.id}> {course.id}-{course.course}-{course.tag} </li> ))} </ul> </> ); }; export default App;
关键修复点
- 同组单选按钮:所有单选按钮设置相同的
name="courseFilter",确保互斥选中 - 状态跟踪:用
selectedTag明确记录当前选中项,直接映射到checked属性实现状态同步 - 性能优化:使用
useMemo缓存过滤结果,避免每次渲染重复计算 - 简化逻辑:去掉冗余的
setFilterData调用,直接通过选中状态推导过滤后的数据
内容的提问来源于stack exchange,提问作者MeAtWork
相关产品推荐
相关产品推荐

