React JS 对数组应用筛选操作后如何保留原始初始数据?
问题解决思路
你出现这个问题的核心是直接修改了存储全量原始数据的lists state,首次筛选后全量数据已经被替换为筛选后的子集,后续筛选自然无法拿到完整数据,甚至会返回空数组。
具体修改方案
1. 拆分数据存储
单独用一个state存储从API拉取的全量原始数据,除了接口请求赋值外永远不修改它。
2. 单独存储筛选条件
将年龄、国家这类筛选条件单独存为state,不要单独存储筛选结果,而是通过计算得到最终渲染列表。
3. 用useMemo计算筛选结果
使用useMemo根据全量数据和筛选条件计算出最终要渲染的列表,既能避免多余的state操作,也能自动缓存结果减少重复计算。
完整代码示例
import { useState, useEffect, useMemo } from 'react'; function YourComponent() { // 存储全量原始数据,仅在接口请求时更新 const [originLists, setOriginLists] = useState([]); // 存储筛选条件 const [ageFilter, setAgeFilter] = useState(''); const [countryFilter, setCountryFilter] = useState(''); // 拉取全量数据 useEffect(() => { const url = "https://domain/api/all"; fetch(url) .then(response => response.json()) .then(res => { setOriginLists(res.json.list); }); }, []); // 计算过滤后的展示列表 const filteredList = useMemo(() => { let list = [...originLists]; // 年龄筛选,有值时才执行过滤 if (ageFilter) { list = list.filter(item => item.age === ageFilter); } // 国家筛选,有值时才执行过滤 if (countryFilter) { list = list.filter(item => item.country === countryFilter); } return list; }, [originLists, ageFilter, countryFilter]); // 渲染时直接使用filteredList即可 return ( <table> {filteredList.map(item => ( <tr key={item.id}> <td>{item.name}</td> <td>{item.age}</td> <td>{item.country}</td> </tr> ))} </table> ) }
额外说明
这个方案天然支持多条件叠加筛选,同时修改年龄和国家筛选条件也能正常得到结果,不需要额外编写监听逻辑,比原来用多个useEffect监听筛选条件修改state的写法性能更高,逻辑也更清晰。
内容的提问来源于stack exchange,提问作者creativated
相关产品推荐
相关产品推荐

