React Redux实现数据搜索过滤及结果在独立页面展示的问题咨询
React+Redux搜索功能问题排查与解决
第一部分:数据过滤逻辑修复
现有代码错误点
- reducer拼写错误:
retrn应为return - 过滤逻辑错位:
JOBS_SEARCH_REQUEST触发时已经将state.jobs置空,JOBS_SEARCH_SUCCESS中对空数组过滤必然返回空结果- 未将用户输入的搜索关键词传入action、reducer,过滤时调用
action.toLowerCase()属于非法操作,应该使用用户输入的searchTerm - reducer返回值结构错误,直接返回过滤后的数组会破坏原有state结构,导致
useSelector无法正常取值
- action未接收搜索关键词参数,无法将搜索条件传递给reducer
- 组件事件绑定错误:
onSubmit事件应该绑定在<form>标签,而非提交按钮 - 异步操作逻辑错误:dispatch是异步执行,dispatch后立刻读取redux状态拿到的是更新前的旧值,直接赋值给
filteredData无效
修正后的代码
1. reducer代码
export const SEARCHReducer = (state = { loading: false, jobs: [], filtered: [] }, action) => { switch (action.type) { case 'JOBS_SEARCH_REQUEST': return { ...state, loading: true } case 'JOBS_SEARCH_SUCCESS': const { payload, searchTerm } = action; const filtered = payload.filter((job)=> job.title.toLowerCase().includes(searchTerm.toLowerCase())); return { ...state, loading: false, jobs: payload, filtered } default: return state } }
2. action代码
// 新增searchTerm作为入参 export const SEARCHAction = (searchTerm) => async (dispatch) => { try { dispatch({ type: 'JOBS_SEARCH_REQUEST' }) const { data } = await axios.get('http://localhost:8000/jobs') dispatch({ type: 'JOBS_SEARCH_SUCCESS', payload: data, searchTerm: searchTerm }) } catch (error) { console.log(error) } }
3. 搜索栏组件代码
import { useNavigate } from 'react-router-dom' function SearchBar() { const [searchTerm , setSearchTerm] = useState('') const dispatch = useDispatch() const navigate = useNavigate() const handleSearch = (e) =>{ e.preventDefault(); // 把搜索关键词传给action dispatch(SEARCHAction(searchTerm)); // 跳转到独立结果页 navigate('/search-result') } return ( <div> {/* onSubmit绑定到form标签 <form onSubmit={handleSearch}> <div> <input onChange={e=>setSearchTerm(e.target.value)} id="search-input" type="text" className="form-control job-field lg:col-span-9 h-12 px-3 outline-none" placeholder="job title, keywords or company name" value={searchTerm} /> <button type="submit" className="btn search-btn border-0 lg:col-span-3"> <i className="fa fa-search mx-1"></i> </button> </div> </form> </div> ) }
第二部分:独立页面展示搜索结果实现方案
使用react-router-dom实现,步骤如下:
- 安装react-router-dom,配置路由规则,新增搜索结果页路由示例:
import { createBrowserRouter, RouterProvider } from 'react-router-dom' import SearchBar from './SearchBar' import SearchResult from './SearchResult' const router = createBrowserRouter([ { path: '/', element: <SearchBar /> }, { path: '/search-result', element: <SearchResult /> }, ])
- 搜索结果页直接从redux取过滤后的数据渲染即可:
function SearchResult() { const searchItems = useSelector((state) => state.searchItems) const { loading, filtered } = searchItems; return ( <div> { loading ? <p>加载中</p> : filtered.map(item => <p key={item.id}>{item.title}</p>) } </div> ) }
内容的提问来源于stack exchange,提问作者fatemeh zamanipour
相关产品推荐
相关产品推荐

