React中基于复选框选中项过滤数据功能不生效问题排查
问题排查与修复方案
存在的问题
- 多选框取消选中时直接修改原state数组,违反React state不可变原则,导致状态更新无法触发重渲染
- 无选中状态下的筛选逻辑错误:拿数据对象和字符串
'3 days ago'直接比较,永远返回空数组;且map回调未写return,表格行不会渲染,还错误访问了不存在的item.includes字段 - 有选中状态下完全没有做筛选逻辑,直接返回全部默认数据,也没有处理无匹配时返回默认数据的规则
- 复选框的value值没有和数据字段的筛选规则做对应,需要明确匹配逻辑:比如
Lastsevendays匹配date_listed为7天内的条目,last_24匹配24小时内的条目
修复后的代码
import React from "react"; import "./styles.css"; import { useState } from "react"; import DefaultData from "./DefaultData"; export default function App() { const [isSelected, setIsSelected] = useState([]); const onChange = (e) => { const checked = e.target.checked; const value = e.target.value; if (checked) { setIsSelected([...isSelected, value]); } else { // 用filter生成新数组,不修改原state setIsSelected(isSelected.filter(item => item !== value)); } }; // 抽离表格数据计算逻辑 const getTableData = () => { // 无选中直接返回默认数据 if (isSelected.length === 0) return DefaultData; // 有选中先筛选,可根据实际数据结构调整筛选规则 const filtered = DefaultData.filter(item => { return isSelected.some(selected => { // 示例规则:选中Lastsevendays匹配7天内数据,选中last_24匹配24小时内数据 if (selected === 'Lastsevendays') { const day = parseInt(item.date_listed); return item.date_listed.includes('days ago') && day <=7; } if (selected === 'last_24') { const hour = parseInt(item.date_listed); return item.date_listed.includes('hours ago') && hour <=24; } return false; }) }) // 筛选结果为空返回默认数据,否则返回筛选结果 return filtered.length ? filtered : DefaultData; } const tableData = getTableData(); return ( <div className="App"> <span> 已选过滤器:{" "} {isSelected.map((i, idx) => ( <span key={idx} style={{marginRight: '8px'}}>{i}</span> ))} </span> <div className="first-search"> <input type="checkbox" className="input-1" value="Lastsevendays" name="last_seven" id="1" onChange={onChange} /> <label htmlFor="1">最近7天</label> </div> <div className="first-search"> <input type="checkbox" className="input-1" name="last24" value="last_24" id="2" onChange={onChange} /> <label htmlFor="2">最近24小时</label> <table> <thead> <tr> <th>Header1</th> <th>Header2</th> <th>Header3</th> </tr> </thead> <tbody> { tableData.map((item, index) => ( <tr key={index}> <td>{item.distance}</td> <td>{item.date_listed}</td> <td>{item.id}</td> </tr> )) } </tbody> </table> </div> </div> ); }
补充说明
可根据DefaultData的实际字段结构调整getTableData里的筛选规则,若数据内有专门的时间戳字段,直接用时间戳计算筛选会更准确。
内容的提问来源于stack exchange,提问作者s life
相关产品推荐
相关产品推荐

