如何实现双向数据过滤?React状态下任务展开/收起问题
解决React项目任务展开/收起的双向过滤问题
你当前的问题核心是直接修改了存储原始数据的state,导致隐藏的任务数据被永久删除,无法恢复。要仅借助state实现双向过滤,正确的做法是保留完整的原始数据副本,用额外的state记录折叠状态,而非直接修改原始数据。
修改方案步骤:
- 保留原始数据的完整state,不对其进行过滤修改
- 新增一个state记录被收起的项目ID列表,通过切换该列表内容控制任务的显示/隐藏
- 渲染时根据折叠状态动态过滤要展示的内容
完整代码示例:
const data = [ { id: 1, title: "Project 01", project_id: null, is_project: true }, { id: 2, title: "Task 01", project_id: 1, is_project: false }, { id: 3, title: "Task 02", project_id: 1, is_project: false }, { id: 4, title: "Project 02", project_id: null, is_project: true }, { id: 5, title: "Task 03", project_id: 4, is_project: false }, ]; const [originalData, setOriginalData] = useState([]); // 存储被收起的项目ID,初始为空(默认所有项目展开) const [collapsedProjects, setCollapsedProjects] = useState([]); useEffect(() => { setOriginalData(data); // 模拟从服务器获取数据,保留完整副本 }, []); // 切换项目的展开/收起状态 const toggleProjectVisibility = (projectId) => { setCollapsedProjects(prev => { if (prev.includes(projectId)) { // 如果项目已收起,移除ID,展开任务 return prev.filter(id => id !== projectId); } else { // 如果项目已展开,添加ID,收起任务 return [...prev, projectId]; } }); }; // 渲染时动态过滤内容 const renderItems = () => { return originalData.filter(item => { // 项目始终显示 if (item.is_project) return true; // 任务仅在所属项目未被收起时显示 return !collapsedProjects.includes(item.project_id); }); }; // 组件内的渲染部分示例 return ( <div> {renderItems().map(item => ( <div key={item.id}> {item.is_project ? ( <div> <button onClick={() => toggleProjectVisibility(item.id)}> {/* 根据状态显示展开/收起图标 */} {collapsedProjects.includes(item.id) ? "+" : "-"} </button> {item.title} </div> ) : ( <div style={{ marginLeft: "20px" }}>{item.title}</div> )} </div> ))} </div> );
关键说明:
originalData始终保留从服务器获取的完整数据,不会被修改collapsedProjects仅记录需要隐藏任务的项目ID,通过切换这个数组来控制显示逻辑- 渲染时通过
filter动态判断哪些任务需要显示,不会破坏原始数据,因此可以实现双向切换
内容的提问来源于stack exchange,提问作者luckydev
相关产品推荐
相关产品推荐

