Redux搜索后清除搜索词无法正确显示原始内容的问题咨询
React+Redux搜索功能修复方案:删除搜索字符后结果无法正确显示
问题根源
你的代码存在几个核心问题,导致删除搜索栏字符时无法正确展示结果:
- 原始数据丢失:搜索时直接修改了Redux state里的
item数组,覆盖了原始数据,后续无法恢复 - 搜索结果嵌套错误:
SEARCH_ITEM中把filter返回的数组又用[]包裹,变成二维数组,导致渲染异常 - Reset功能失效:
RESET动作只是返回当前的item,而非原始数据 - 未实现实时搜索:当前需要点击搜索按钮才触发过滤,不符合“基于搜索栏当前内容展示结果”的需求
修复步骤
1. 修改Reducer:保留原始数据,分离搜索结果
修改Reducer的初始状态,新增originalItems存储原始数据,filteredItems存储搜索结果,避免覆盖原始数据:
const INITIAL_STATE = { originalItems: [], // 存储所有原始数据 filteredItems: [], // 存储搜索过滤后的结果 loading: false, }; function addReducer(state = INITIAL_STATE, action) { switch (action.type) { case "ADD_ITEM": const newOriginalItems = [...state.originalItems, action.name]; return { ...state, originalItems: newOriginalItems, filteredItems: newOriginalItems, // 添加后同步更新过滤结果 }; case "REMOVE_ITEM": const updatedOriginal = state.originalItems.filter(item => item !== action.name); return { ...state, originalItems: updatedOriginal, filteredItems: updatedOriginal, // 删除后同步更新过滤结果 }; case "SEARCH_ITEM": const searchTerm = action.searchTerm.trim(); let result = [...state.originalItems]; if (searchTerm) { result = result.filter(item => item.includes(searchTerm)); } return { ...state, loading: false, filteredItems: result, }; case "RESET": return { ...state, filteredItems: [...state.originalItems], // 重置为原始数据 }; default: return state; } } export default addReducer;
2. 修改App.js:实现实时搜索,调整数据读取逻辑
- 移除搜索按钮,在输入框变化时直接触发搜索
- 从Redux读取
filteredItems用于渲染 - 修正初始数据判断的错误逻辑
import logo from "./logo.svg"; import "./App.css"; import React, { useState } from "react"; import { useSelector, useDispatch } from "react-redux"; function App() { const [name, setName] = useState(""); const [searchTerm, setSearchterm] = useState(""); const dispatch = useDispatch(); const { originalItems, filteredItems, loading } = useSelector((state) => state.add); const handleChange = (e) => { setName(e.target.value); }; // 实时搜索:输入框变化时触发 const handleSearch = (e) => { const term = e.target.value; setSearchterm(term); dispatch({ type: "SEARCH_ITEM", searchTerm: term }); }; const Submithandler = () => { dispatch({ type: "ADD_ITEM", name }); setName(""); }; const reset = () => { setSearchterm(""); dispatch({ type: "RESET" }); }; // 初始数据判断:原始数据为空时提示 if (originalItems.length === 0) { return <p>No data</p>; } return ( <div className="App"> {loading && <p>loading</p>} {/* 实时搜索输入框,无需单独搜索按钮 */} <input value={searchTerm} onChange={handleSearch} placeholder="输入关键词搜索" /> <button onClick={reset}>reset</button> <input value={name} onChange={handleChange} placeholder="输入内容添加" /> <button onClick={Submithandler}>Add</button> {filteredItems.length === 0 && <p>no item matched</p>} {filteredItems.map((item, index) => { return ( <div key={index}> {item} <button onClick={() => dispatch({ type: "REMOVE_ITEM", name: item })}> Remove </button> </div> ); })} </div> ); } export default App;
关键改进点说明
- 数据分离:用
originalItems保存所有原始数据,filteredItems只存过滤结果,确保原始数据不被修改 - 实时搜索:输入框
onChange时直接触发搜索动作,无需点击按钮 - 修复嵌套数组问题:去掉
SEARCH_ITEM中多余的数组包裹,直接返回filter结果 - Reset功能正常:重置时将
filteredItems恢复为原始数据 - 添加/删除同步更新:添加或删除数据时,同时更新原始数据和过滤结果,保证一致性
内容的提问来源于stack exchange,提问作者user20528955
相关产品推荐
相关产品推荐

