React中如何基于输入筛选全量API数据(初始仅展示3条)
问题:筛选仅作用于初始3条数据,无法覆盖全量API数据
需求与Bug说明
- 功能需求:通过API获取数据并展示为列表,输入框实时筛选匹配数据;初始仅展示3条数据,点击「view more」按钮后展示全量列表
- 当前Bug:未点击「view more」时,筛选仅针对初始3条数据,无法对全量API数据进行筛选
现有代码
父组件代码:
const [apiData, setApiData] = useState([]); const [viewAllRoles, setViewAllRoles] = useState(false); const [filterData, setFilterData] = useState(""); const searchValue = useRef(""); useEffect(() => { axios .get("https://advisoryalpha.github.io/skill-assessments/identities.json") .then((res) => { setApiData(res.data); }) .catch((error) => { alert(error.message); }); }, []); // 原代码中return内部定义函数的写法有误,需移到return外部 const viewRolesHandler = () => { setViewAllRoles(!viewAllRoles); }; return ( <> <input type="text" ref={searchValue} value={filterData} onChange={(e) => setFilterData(e.target.value)} /> {/* 原input标签未正确闭合,修正为自闭合标签 */} <ul> <ShowDataLength apiData={apiData} filterData={filterData} viewAllRoles={viewAllRoles} setName={/* 你的setName方法 */} setRole={/* 你的setRole方法 */} /> <button id="view-all__btn" style={{ marginTop: "10px", marginBottom: "5px" }} onClick={viewRolesHandler} > {!viewAllRoles ? "View all" : "View less"} </button> </ul> </> );
ShowDataLength组件代码:
const ShowDataLength = ({ apiData, filterData, setName, setRole, viewAllRoles, }) => { function dataHandler() { return !viewAllRoles ? apiData.slice(0, 3) : apiData; } return dataHandler() .filter( (el) => el.name.toLowerCase().includes(filterData.toLowerCase()) || filterData === "" ) .map((el, index) => ( <li key={index} onClick={() => { setName(el.name); setRole(el.role); }} > <h4>{el.name}</h4> <h5>{el.role}</h5> </li> )); };
问题根源
当前逻辑是先截取前3条数据,再对这3条进行筛选,导致未点击「view more」时,筛选范围被限制在初始3条内,无法触达全量API数据。
解决方案
调整逻辑顺序:先对全量API数据进行筛选,再根据viewAllRoles状态决定显示全部筛选结果还是仅前3条。
修改后的ShowDataLength组件代码:
const ShowDataLength = ({ apiData, filterData, setName, setRole, viewAllRoles, }) => { // 第一步:对全量数据执行筛选逻辑 const filteredData = apiData.filter( (el) => el.name.toLowerCase().includes(filterData.toLowerCase()) || filterData === "" ); // 第二步:根据viewAllRoles状态决定最终展示的数量 const displayData = viewAllRoles ? filteredData : filteredData.slice(0, 3); return displayData.map((el, index) => ( <li key={el.id || index} {/* 建议用数据自身的唯一id作为key,避免index可能导致的渲染异常 */} onClick={() => { setName(el.name); setRole(el.role); }} > <h4>{el.name}</h4> <h5>{el.role}</h5> </li> )); };
额外优化点
- 父组件中
viewRolesHandler不能定义在return内部,需移到外部符合React规范 - 列表项key优先使用数据自身的唯一标识(如
el.id),而非index,提升渲染稳定性与性能
内容的提问来源于stack exchange,提问作者maxheezy's
相关产品推荐
相关产品推荐

