React组件过滤函数异常:清空搜索框无法恢复完整成员列表
问题原因
你遇到的问题核心是过滤操作直接覆盖了原始的成员列表数据。页面加载时collegiateList保存了完整数据,但每次调用filter函数时,都会把过滤后的结果重新赋值给collegiateList,导致原始数据被覆盖。当搜索框清空后,你只能基于最后一次过滤后的结果再过滤,自然无法恢复完整列表。
解决方案
需要单独维护一份原始完整成员列表,过滤操作始终基于这份原始数据进行,而不是修改用来展示的列表。具体步骤:
- 新增一个状态
originalCollegiateList,专门存储从接口获取的完整成员数据 - 接口请求成功后,同时更新原始列表和展示列表
- 修改过滤逻辑,基于原始列表进行过滤,将结果赋值给展示列表
- 通过监听
searchCollegiate状态变化触发过滤,更符合React状态管理逻辑
修改后的完整代码
import React, { useState, useEffect } from 'react' import { useDispatch } from "react-redux"; import { getCollegiate } from '../../api/drupalAPI' import {Collegiate} from '@icofcv/common'; import { useNavigate } from "react-router-dom"; import Button from 'react-bootstrap/Button'; import Form from 'react-bootstrap/Form'; import './CollegiateList.css'; export const CollegiateList = () => { // 原始完整列表:仅在接口请求后更新,不参与过滤修改 const [originalCollegiateList, setOriginalCollegiateList] = useState<Collegiate[]>([]); // 展示用列表:根据搜索词过滤后的结果 const [collegiateList, setCollegiateList] = useState<Collegiate[]>([]); const [searchCollegiate, setSearchCollegiate] = useState(""); const fetchCollegiateList = async () => { getCollegiate().then((response)=>{ console.log(response) // 同时更新原始列表和展示列表 setOriginalCollegiateList(response); setCollegiateList(response); }).catch ( (error) => { console.error(error); throw error; }); } const handleChange = e => { setSearchCollegiate(e.target.value); } // 监听搜索词变化,自动触发过滤 useEffect(() => { if (!searchCollegiate.trim()) { // 搜索框为空时,直接展示完整列表 setCollegiateList(originalCollegiateList); return; } // 基于原始列表进行过滤 const term = searchCollegiate.toLowerCase(); const resultSearch = originalCollegiateList.filter((element)=>{ return element.firstname.toString().toLowerCase().includes(term) || element.lastname.toString().toLowerCase().includes(term); }); setCollegiateList(resultSearch); }, [searchCollegiate, originalCollegiateList]); useEffect(() => { fetchCollegiateList(); }, []); return( <> <div> <Form className="d-flex"> <Form.Control type="search" value={searchCollegiate} placeholder="Search" className="me-2" aria-label="Search" onChange={handleChange} /> {/* <Button variant="outline-success">Search</Button> */} </Form> </div> <div className="content-collegiatelist"> <table> <tbody> <tr> <th>Tipo</th> <th>Colegiado</th> <th>Nombre</th> <th>Apellido</th> <th>Provincia</th> </tr> { collegiateList.map((collegiate, index) => ( // 推荐用数据中唯一标识字段替换index,比如collegiate.id <div className="content-table-td" key={index}> <tr> <td>{collegiate.color}</td> <td>{collegiate.collegiate}</td> <td>{collegiate.firstname}</td> <td>{collegiate.lastname}</td> <td>{collegiate.provincia}</td> </tr> </div> )) } </tbody> </table> </div> </> ) }
额外优化点
- 给
map循环元素添加了key属性,避免React警告 - 提取重复的小写转换操作,减少不必要的计算
- 搜索词为空时直接赋值原始列表,简化逻辑并提升性能
内容的提问来源于stack exchange,提问作者cuencadelrio
相关产品推荐
相关产品推荐

