React搜索筛选后如何清除状态恢复初始数据?
解决React搜索清空后无法恢复全部数据的问题
你的代码核心问题是直接覆盖了原始数据状态,并且重复发起不必要的接口请求。当搜索词清空时,没有原始数据可以恢复,所以页面停留在最后一次筛选的结果。下面是具体的修复方案:
核心思路
- 单独存储一份原始数据副本,避免被筛选结果覆盖
- 基于原始数据做本地筛选,不用每次搜索都重新请求接口
- 当搜索词为空或长度不足时,直接展示全部原始数据
修改后的完整代码
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
相关产品推荐
相关产品推荐

