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

React搜索筛选后如何清除状态恢复初始数据?

解决React搜索清空后无法恢复全部数据的问题

你的代码核心问题是直接覆盖了原始数据状态,并且重复发起不必要的接口请求。当搜索词清空时,没有原始数据可以恢复,所以页面停留在最后一次筛选的结果。下面是具体的修复方案:

核心思路

  1. 单独存储一份原始数据副本,避免被筛选结果覆盖
  2. 基于原始数据做本地筛选,不用每次搜索都重新请求接口
  3. 当搜索词为空或长度不足时,直接展示全部原始数据

修改后的完整代码

import { FC, useEffect, useState } from 'react';
import './style.css';

export const App: FC<{ name: string }> = ({ name }) => {
  // 存储原始完整数据
  const [originalUsers, setOriginalUsers] = useState([]);
  // 存储当前要展示的筛选后数据
  const [displayUsers, setDisplayUsers] = useState([]);
  const [searched, setSearched] = useState('');

  useEffect(() => {
    async function getUsers() {
      const response = await fetch('https://jsonplaceholder.typicode.com/users').then(res => res.json());
      // 首次加载同时保存原始数据和展示数据
      setOriginalUsers(response);
      setDisplayUsers(response);
    }
    getUsers();
  }, []);

  useEffect(() => {
    if (searched.trim().length >= 2) {
      // 基于原始数据做本地筛选,不用重新请求接口
      const filtered = originalUsers.filter(user => 
        user.name.toLowerCase().includes(searched.toLowerCase())
      );
      setDisplayUsers(filtered);
    } else {
      // 搜索词为空或长度不够时,恢复展示全部原始数据
      setDisplayUsers(originalUsers);
    }
  }, [searched, originalUsers]);

  return (
    <>
      <input
        type="text"
        placeholder="Enter name"
        value={searched}
        onChange={(ev) => setSearched(ev.target.value)}
      />
      {displayUsers.map((user) => <p key={user.id}>{user.name}</p>)}
    </>
  );
};

关键修改点说明

  • 新增originalUsers状态专门存储从接口获取的完整数据,永远不修改它
  • 用displayUsers状态控制页面展示的内容,根据搜索词动态更新
  • 移除了重复的接口请求,直接在本地基于原始数据筛选,性能更好
  • 当搜索词长度不足2或清空时,强制将displayUsers恢复为originalUsers,确保展示全部数据
  • 给列表项添加了key属性,符合React列表渲染的规范

更简洁的优化方案(无需额外useEffect)

你甚至可以不用单独的displayUsers状态,直接在渲染时实时筛选:

import { FC, useEffect, useState } from 'react';
import './style.css';

export const App: FC<{ name: string }> = ({ name }) => {
  const [originalUsers, setOriginalUsers] = useState([]);
  const [searched, setSearched] = useState('');

  useEffect(() => {
    async function getUsers() {
      const response = await fetch('https://jsonplaceholder.typicode.com/users').then(res => res.json());
      setOriginalUsers(response);
    }
    getUsers();
  }, []);

  // 实时计算要展示的内容
  const displayUsers = searched.trim().length >= 2 
    ? originalUsers.filter(user => 
        user.name.toLowerCase().includes(searched.toLowerCase())
      )
    : originalUsers;

  return (
    <>
      <input
        type="text"
        placeholder="Enter name"
        value={searched}
        onChange={(ev) => setSearched(ev.target.value)}
      />
      {displayUsers.map((user) => <p key={user.id}>{user.name}</p>)}
    </>
  );
};

这种方式更简洁,减少了状态的数量,逻辑更直观。

内容的提问来源于stack exchange,提问作者ghost_of_the_code

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:03:32