You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 10:24:08